Merge branch 'master' into XACE-SELINUX

Conflicts:

	GL/glx/glxscreens.c
	hw/xnest/Screen.c
	render/glyph.c
	render/glyphstr.h
	render/render.c
This commit is contained in:
Eamon Walsh 2007-10-25 12:19:30 -04:00 committed by Eamon Walsh
commit b633d54b94
44 changed files with 1203 additions and 1877 deletions

View File

@ -53,7 +53,6 @@ libglx_la_SOURCES = \
glxserver.h \ glxserver.h \
glxutil.c \ glxutil.c \
glxutil.h \ glxutil.h \
glxvisuals.c \
indirect_dispatch.c \ indirect_dispatch.c \
indirect_dispatch.h \ indirect_dispatch.h \
indirect_dispatch_swap.c \ indirect_dispatch_swap.c \

View File

@ -59,16 +59,91 @@
#include "indirect_table.h" #include "indirect_table.h"
#include "indirect_util.h" #include "indirect_util.h"
/************************************************************************/
void void
GlxSetRenderTables (struct _glapi_table *table) GlxSetRenderTables (struct _glapi_table *table)
{ {
_glapi_set_dispatch (table); _glapi_set_dispatch (table);
} }
static int
validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err)
{
/*
** Check if screen exists.
*/
if (screen >= screenInfo.numScreens) {
client->errorValue = screen;
*err = BadValue;
return FALSE;
}
*pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
/************************************************************************/ return TRUE;
}
static int
validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
__GLcontextModes **config, int *err)
{
__GLcontextModes *m;
for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next)
if (m->fbconfigID == id) {
*config = m;
return TRUE;
}
client->errorValue = id;
*err = __glXError(GLXBadFBConfig);
return FALSE;
}
static int
validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
__GLcontextModes **config, int *err)
{
int i;
for (i = 0; i < pGlxScreen->numVisuals; i++)
if (pGlxScreen->visuals[i]->visualID == id) {
*config = pGlxScreen->visuals[i];
return TRUE;
}
client->errorValue = id;
*err = BadValue;
return FALSE;
}
static int
validGlxFBConfigForWindow(ClientPtr client, __GLcontextModes *config,
DrawablePtr pDraw, int *err)
{
ScreenPtr pScreen = pDraw->pScreen;
VisualPtr pVisual = NULL;
XID vid;
int i;
vid = wVisual((WindowPtr)pDraw);
for (i = 0; i < pScreen->numVisuals; i++) {
if (pScreen->visuals[i].vid == vid) {
pVisual = &pScreen->visuals[i];
break;
}
}
/* FIXME: What exactly should we check here... */
if (pVisual->class != _gl_convert_to_x_visual_type(config->visualType) ||
!(config->drawableType & GLX_WINDOW_BIT)) {
client->errorValue = pDraw->id;
*err = BadMatch;
return FALSE;
}
return TRUE;
}
void void
__glXContextDestroy(__GLXcontext *context) __glXContextDestroy(__GLXcontext *context)
@ -111,59 +186,15 @@ static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen,
static int static int
DoCreateContext(__GLXclientState *cl, GLXContextID gcId, DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
GLXContextID shareList, VisualID visual, GLXContextID shareList, __GLcontextModes *config,
GLuint screen, GLboolean isDirect) __GLXscreen *pGlxScreen, GLboolean isDirect)
{ {
ClientPtr client = cl->client; ClientPtr client = cl->client;
VisualPtr pVisual; VisualPtr pVisual;
ScreenPtr pScreen;
__GLXcontext *glxc, *shareglxc; __GLXcontext *glxc, *shareglxc;
__GLcontextModes *modes;
__GLXscreen *pGlxScreen;
GLint i;
LEGAL_NEW_RESOURCE(gcId, client); LEGAL_NEW_RESOURCE(gcId, client);
/*
** Check if screen exists.
*/
if (screen >= screenInfo.numScreens) {
client->errorValue = screen;
return BadValue;
}
pScreen = screenInfo.screens[screen];
pGlxScreen = glxGetScreen(pScreen);
/*
** 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;
return BadValue;
}
/*
** Get configuration of the visual. This assumes that the
** glxScreen structure contains visual configurations only for the
** subset of Visuals that are supported by this implementation of the
** OpenGL.
*/
modes = _gl_context_modes_find_visual( pGlxScreen->modes, visual );
if (modes == NULL) {
/*
** Visual not support on this screen by this OpenGL implementation.
*/
client->errorValue = visual;
return BadValue;
}
/* /*
** Find the display list space that we want to share. ** Find the display list space that we want to share.
** **
@ -206,9 +237,9 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
** Allocate memory for the new context ** Allocate memory for the new context
*/ */
if (!isDirect) if (!isDirect)
glxc = pGlxScreen->createContext(pGlxScreen, modes, shareglxc); glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc);
else else
glxc = __glXdirectContextCreate(pGlxScreen, modes, shareglxc); glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc);
if (!glxc) { if (!glxc) {
return BadAlloc; return BadAlloc;
} }
@ -217,10 +248,10 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
** Initially, setup the part of the context that could be used by ** Initially, setup the part of the context that could be used by
** a GL core that needs windowing information (e.g., Mesa). ** a GL core that needs windowing information (e.g., Mesa).
*/ */
glxc->pScreen = pScreen; glxc->pScreen = pGlxScreen->pScreen;
glxc->pGlxScreen = pGlxScreen; glxc->pGlxScreen = pGlxScreen;
glxc->pVisual = pVisual; glxc->pVisual = pVisual;
glxc->modes = modes; glxc->modes = config;
/* /*
** Register this context as a resource. ** Register this context as a resource.
@ -245,34 +276,54 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
return Success; return Success;
} }
int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
return DoCreateContext( cl, req->context, req->shareList, req->visual, __GLcontextModes *config;
req->screen, req->isDirect ); __GLXscreen *pGlxScreen;
} int err;
if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
return err;
if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
return err;
return DoCreateContext(cl, req->context, req->shareList,
config, pGlxScreen, req->isDirect);
}
int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
return DoCreateContext( cl, req->context, req->shareList, req->fbconfig, __GLcontextModes *config;
req->screen, req->isDirect ); __GLXscreen *pGlxScreen;
} int err;
if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
return err;
if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
return err;
return DoCreateContext(cl, req->context, req->shareList,
config, pGlxScreen, req->isDirect);
}
int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXCreateContextWithConfigSGIXReq *req = xGLXCreateContextWithConfigSGIXReq *req =
(xGLXCreateContextWithConfigSGIXReq *) pc; (xGLXCreateContextWithConfigSGIXReq *) pc;
return DoCreateContext( cl, req->context, req->shareList, req->fbconfig, __GLcontextModes *config;
req->screen, req->isDirect ); __GLXscreen *pGlxScreen;
} int err;
/* if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
** Destroy a GL context as an X resource. return err;
*/ if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
return err;
return DoCreateContext(cl, req->context, req->shareList,
config, pGlxScreen, req->isDirect);
}
int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc) int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc)
{ {
ClientPtr client = cl->client; ClientPtr client = cl->client;
@ -407,9 +458,7 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
int *error) int *error)
{ {
DrawablePtr pDraw; DrawablePtr pDraw;
__GLcontextModes *modes;
__GLXdrawable *pGlxDraw; __GLXdrawable *pGlxDraw;
VisualID vid;
int rc; int rc;
/* This is the GLX 1.3 case - the client passes in a GLXWindow or /* This is the GLX 1.3 case - the client passes in a GLXWindow or
@ -446,21 +495,17 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
return NULL; return NULL;
} }
vid = wVisual((WindowPtr)pDraw);
modes = _gl_context_modes_find_visual(glxc->pGlxScreen->modes, vid);
/* We're binding an X Window for the first time and need to create /* We're binding an X Window for the first time and need to create
* a GLX drawable for it. First check that the drawable screen * a GLX drawable for it. Check that the drawable screen matches
* and fbconfig matches the context ditto. */ * the context screen and that the context fbconfig is compatible
if (pDraw->pScreen != glxc->pScreen || modes != glxc->modes) { * with the window visual. */
client->errorValue = drawId; if (pDraw->pScreen != glxc->pScreen ||
*error = BadMatch; !validGlxFBConfigForWindow(client, glxc->modes, pDraw, error))
return NULL; return NULL;
}
pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen, pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
pDraw, GLX_DRAWABLE_WINDOW, pDraw, GLX_DRAWABLE_WINDOW,
drawId, modes); drawId, glxc->modes);
/* since we are creating the drawablePrivate, drawId should be new */ /* since we are creating the drawablePrivate, drawId should be new */
if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
@ -830,29 +875,24 @@ int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc)
} }
static int int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
DoGetVisualConfigs(__GLXclientState *cl, unsigned screen)
{ {
xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
ClientPtr client = cl->client; ClientPtr client = cl->client;
xGLXGetVisualConfigsReply reply; xGLXGetVisualConfigsReply reply;
__GLXscreen *pGlxScreen; __GLXscreen *pGlxScreen;
__GLcontextModes *modes; __GLcontextModes *modes;
CARD32 buf[__GLX_TOTAL_CONFIG]; CARD32 buf[__GLX_TOTAL_CONFIG];
int p; int p, i, err;
__GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_VARIABLES;
__GLX_DECLARE_SWAP_ARRAY_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
if (screen >= screenInfo.numScreens) { if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
/* The client library must send a valid screen number. */ return err;
client->errorValue = screen;
return BadValue;
}
pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
reply.numVisuals = pGlxScreen->numUsableVisuals; reply.numVisuals = pGlxScreen->numVisuals;
reply.numProps = __GLX_TOTAL_CONFIG; reply.numProps = __GLX_TOTAL_CONFIG;
reply.length = (pGlxScreen->numUsableVisuals * __GLX_SIZE_CARD32 * reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG) >> 2;
__GLX_TOTAL_CONFIG) >> 2;
reply.type = X_Reply; reply.type = X_Reply;
reply.sequenceNumber = client->sequence; reply.sequenceNumber = client->sequence;
@ -865,11 +905,9 @@ DoGetVisualConfigs(__GLXclientState *cl, unsigned screen)
WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) { for (i = 0; i < pGlxScreen->numVisuals; i++) {
if (modes->visualID == 0) { modes = pGlxScreen->visuals[i];
/* not a usable visual */
continue;
}
p = 0; p = 0;
buf[p++] = modes->visualID; buf[p++] = modes->visualID;
buf[p++] = _gl_convert_to_x_visual_type( modes->visualType ); buf[p++] = _gl_convert_to_x_visual_type( modes->visualType );
@ -919,93 +957,6 @@ DoGetVisualConfigs(__GLXclientState *cl, unsigned screen)
return Success; return Success;
} }
int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
{
xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
return DoGetVisualConfigs(cl, req->screen);
}
/* Composite adds a 32 bit ARGB visual after glxvisuals.c have created
* the context modes for the screens. This visual is useful for GLX
* pixmaps, so we create a single mode for this visual with no extra
* buffers. */
static void
__glXCreateARGBConfig(__GLXscreen *screen)
{
__GLcontextModes *modes;
VisualPtr visual;
int i;
/* search for a 32-bit visual */
visual = NULL;
for (i = 0; i < screen->pScreen->numVisuals; i++)
if (screen->pScreen->visuals[i].nplanes == 32) {
visual = &screen->pScreen->visuals[i];
break;
}
if (visual == NULL || visual->class != TrueColor)
return;
/* Stop now if we already added the mode. */
if (_gl_context_modes_find_visual (screen->modes, visual->vid))
return;
modes = _gl_context_modes_create(1, sizeof(__GLcontextModes));
if (modes == NULL)
return;
/* Insert this new mode at the TAIL of the linked list.
* Previously, the mode was incorrectly inserted at the head of the
* list, causing find_mesa_visual() to be off by one. This would
* GLX clients to blow up if they attempted to use the last mode
* in the list!
*/
{
__GLcontextModes *prev = NULL, *m;
for (m = screen->modes; m; m = m->next)
prev = m;
if (prev)
prev->next = modes;
else
screen->modes = modes;
}
screen->numUsableVisuals++;
screen->numVisuals++;
modes->visualID = visual->vid;
modes->fbconfigID = visual->vid;
modes->visualType = GLX_TRUE_COLOR;
modes->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
modes->renderType = GLX_RGBA_BIT;
modes->xRenderable = GL_TRUE;
modes->rgbMode = TRUE;
modes->colorIndexMode = FALSE;
modes->doubleBufferMode = FALSE;
modes->stereoMode = FALSE;
modes->haveAccumBuffer = FALSE;
modes->redBits = visual->bitsPerRGBValue;;
modes->greenBits = visual->bitsPerRGBValue;
modes->blueBits = visual->bitsPerRGBValue;
modes->alphaBits = visual->bitsPerRGBValue;
modes->rgbBits = 4 * visual->bitsPerRGBValue;
modes->indexBits = 0;
modes->level = 0;
modes->numAuxBuffers = 0;
modes->haveDepthBuffer = FALSE;
modes->depthBits = 0;
modes->haveStencilBuffer = FALSE;
modes->stencilBits = 0;
modes->visualRating = GLX_NON_CONFORMANT_CONFIG;
}
#define __GLX_TOTAL_FBCONFIG_ATTRIBS (28) #define __GLX_TOTAL_FBCONFIG_ATTRIBS (28)
#define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2) #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
/** /**
@ -1025,25 +976,15 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
xGLXGetFBConfigsReply reply; xGLXGetFBConfigsReply reply;
__GLXscreen *pGlxScreen; __GLXscreen *pGlxScreen;
CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH]; CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH];
int p; int p, err;
__GLcontextModes *modes; __GLcontextModes *modes;
__GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_VARIABLES;
__GLX_DECLARE_SWAP_ARRAY_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err))
return err;
if (screen >= screenInfo.numScreens) { reply.numFBConfigs = pGlxScreen->numFBConfigs;
/* The client library must send a valid screen number. */
client->errorValue = screen;
return BadValue;
}
pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
/* Create the "extra" 32bpp ARGB visual, if not already added.
* XXX This is questionable place to do so! Re-examine this someday.
*/
__glXCreateARGBConfig(pGlxScreen);
reply.numFBConfigs = pGlxScreen->numUsableVisuals;
reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS; reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS;
reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs); reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs);
reply.type = X_Reply; reply.type = X_Reply;
@ -1058,18 +999,14 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) { for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) {
if (modes->visualID == 0) {
/* not a usable visual */
continue;
}
p = 0; p = 0;
#define WRITE_PAIR(tag,value) \ #define WRITE_PAIR(tag,value) \
do { buf[p++] = tag ; buf[p++] = value ; } while( 0 ) do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
WRITE_PAIR( GLX_VISUAL_ID, modes->visualID ); WRITE_PAIR( GLX_VISUAL_ID, modes->visualID );
WRITE_PAIR( GLX_FBCONFIG_ID, modes->visualID ); WRITE_PAIR( GLX_FBCONFIG_ID, modes->fbconfigID );
WRITE_PAIR( GLX_X_RENDERABLE, GL_TRUE ); WRITE_PAIR( GLX_X_RENDERABLE, GL_TRUE );
WRITE_PAIR( GLX_RGBA, modes->rgbMode ); WRITE_PAIR( GLX_RGBA, modes->rgbMode );
@ -1089,12 +1026,7 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits ); WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits );
WRITE_PAIR( GLX_DEPTH_SIZE, modes->depthBits ); WRITE_PAIR( GLX_DEPTH_SIZE, modes->depthBits );
WRITE_PAIR( GLX_STENCIL_SIZE, modes->stencilBits ); WRITE_PAIR( GLX_STENCIL_SIZE, modes->stencilBits );
WRITE_PAIR( GLX_X_VISUAL_TYPE, modes->visualType ); WRITE_PAIR( GLX_X_VISUAL_TYPE, modes->visualType );
/*
** Add token/value pairs for extensions.
*/
WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating ); WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating );
WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel ); WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel );
WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed ); WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed );
@ -1127,44 +1059,18 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
} }
static int static int
DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId, DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config,
DrawablePtr pDraw, XID glxDrawableId, int type) DrawablePtr pDraw, XID glxDrawableId, int type)
{ {
ScreenPtr pScreen;
VisualPtr pVisual;
__GLXscreen *pGlxScreen;
__GLXdrawable *pGlxDraw; __GLXdrawable *pGlxDraw;
__GLcontextModes *modes;
int i;
LEGAL_NEW_RESOURCE(glxDrawableId, client); LEGAL_NEW_RESOURCE(glxDrawableId, client);
/* Check if screen of the fbconfig matches screen of drawable. */ if (pGlxScreen->pScreen != pDraw->pScreen)
pScreen = pDraw->pScreen;
if (screenNum != pScreen->myNum)
return BadMatch; return BadMatch;
/* If this fbconfig has a corresponding VisualRec the number of
* planes must match the drawable depth. */
pVisual = pScreen->visuals;
for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
if (pVisual->vid == fbconfigId && pVisual->nplanes != pDraw->depth)
return BadMatch;
}
/* Get configuration of the visual. */
pGlxScreen = glxGetScreen(pScreen);
modes = _gl_context_modes_find_visual(pGlxScreen->modes, fbconfigId);
if (modes == NULL) {
/* Visual not support on this screen by this OpenGL implementation. */
client->errorValue = fbconfigId;
return BadValue;
}
/* FIXME: We need to check that the window visual is compatible
* with the specified fbconfig. */
pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type, pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type,
glxDrawableId, modes); glxDrawableId, config);
if (pGlxDraw == NULL) if (pGlxDraw == NULL)
return BadAlloc; return BadAlloc;
@ -1177,7 +1083,7 @@ DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
} }
static int static int
DoCreateGLXPixmap(ClientPtr client, int screenNum, XID fbconfigId, DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config,
XID drawableId, XID glxDrawableId) XID drawableId, XID glxDrawableId)
{ {
DrawablePtr pDraw; DrawablePtr pDraw;
@ -1189,7 +1095,7 @@ DoCreateGLXPixmap(ClientPtr client, int screenNum, XID fbconfigId,
return BadPixmap; return BadPixmap;
} }
err = DoCreateGLXDrawable(client, screenNum, fbconfigId, pDraw, err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw,
glxDrawableId, GLX_DRAWABLE_PIXMAP); glxDrawableId, GLX_DRAWABLE_PIXMAP);
if (err == Success) if (err == Success)
@ -1235,17 +1141,32 @@ determineTextureTarget(XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs)
int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
__GLcontextModes *config;
__GLXscreen *pGlxScreen;
int err;
return DoCreateGLXPixmap(cl->client, req->screen, req->visual, if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
return err;
if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
return err;
return DoCreateGLXPixmap(cl->client, pGlxScreen, config,
req->pixmap, req->glxpixmap); req->pixmap, req->glxpixmap);
} }
int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
__GLcontextModes *config;
__GLXscreen *pGlxScreen;
int err; int err;
err = DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig, if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
return err;
if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
return err;
err = DoCreateGLXPixmap(cl->client, pGlxScreen, config,
req->pixmap, req->glxpixmap); req->pixmap, req->glxpixmap);
if (err != Success) if (err != Success)
return err; return err;
@ -1260,9 +1181,17 @@ int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXCreateGLXPixmapWithConfigSGIXReq *req = xGLXCreateGLXPixmapWithConfigSGIXReq *req =
(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
__GLcontextModes *config;
__GLXscreen *pGlxScreen;
int err;
return DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig, if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
req->pixmap, req->glxpixmap); return err;
if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
return err;
return DoCreateGLXPixmap(cl->client, pGlxScreen,
config, req->pixmap, req->glxpixmap);
} }
@ -1286,6 +1215,11 @@ static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
return __glXError(GLXBadPbuffer); return __glXError(GLXBadPbuffer);
} }
} }
if (type == GLX_DRAWABLE_PIXMAP) {
((PixmapPtr) pGlxDraw->pDraw)->refcnt--;
}
FreeResource(glxdrawable, FALSE); FreeResource(glxdrawable, FALSE);
return Success; return Success;
@ -1309,29 +1243,23 @@ static int
DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
int width, int height, XID glxDrawableId) int width, int height, XID glxDrawableId)
{ {
ScreenPtr pScreen; __GLcontextModes *config;
VisualPtr pVisual; __GLXscreen *pGlxScreen;
PixmapPtr pPixmap; PixmapPtr pPixmap;
int i; int err;
pScreen = screenInfo.screens[screenNum]; if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
return err;
pVisual = pScreen->visuals; if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { return err;
if (pVisual->vid == fbconfigId)
break;
}
if (i == pScreen->numVisuals)
return __glXError(GLXBadFBConfig);
__glXenterServer(GL_FALSE); __glXenterServer(GL_FALSE);
pPixmap = (*pScreen->CreatePixmap) (pScreen, pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen,
width, height, pVisual->nplanes); width, height, config->rgbBits);
__glXleaveServer(GL_FALSE); __glXleaveServer(GL_FALSE);
return DoCreateGLXDrawable(client, screenNum, fbconfigId, return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
&pPixmap->drawable, glxDrawableId, glxDrawableId, GLX_DRAWABLE_PBUFFER);
GLX_DRAWABLE_PBUFFER);
} }
int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
@ -1428,17 +1356,27 @@ int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
{ {
xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
__GLcontextModes *config;
__GLXscreen *pGlxScreen;
ClientPtr client = cl->client; ClientPtr client = cl->client;
DrawablePtr pDraw; DrawablePtr pDraw;
int err; int err;
if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
return err;
if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
return err;
err = dixLookupDrawable(&pDraw, req->window, client, 0, DixUnknownAccess); err = dixLookupDrawable(&pDraw, req->window, client, 0, DixUnknownAccess);
if (err != Success || pDraw->type != DRAWABLE_WINDOW) { if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
client->errorValue = req->window; client->errorValue = req->window;
return BadWindow; return BadWindow;
} }
return DoCreateGLXDrawable(client, req->screen, req->fbconfig, if (!validGlxFBConfigForWindow(client, config, pDraw, &err))
return err;
return DoCreateGLXDrawable(client, pGlxScreen, config,
pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW); pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW);
} }
@ -2338,23 +2276,15 @@ int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
ClientPtr client = cl->client; ClientPtr client = cl->client;
xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
xGLXQueryExtensionsStringReply reply; xGLXQueryExtensionsStringReply reply;
GLuint screen; __GLXscreen *pGlxScreen;
size_t n, length; size_t n, length;
const char *ptr;
char *buf; char *buf;
int err;
screen = req->screen; if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
/* return err;
** Check if screen exists.
*/
if (screen >= screenInfo.numScreens) {
client->errorValue = screen;
return BadValue;
}
ptr = glxGetScreen(screenInfo.screens[screen])->GLXextensions; n = strlen(pGlxScreen->GLXextensions) + 1;
n = strlen(ptr) + 1;
length = __GLX_PAD(n) >> 2; length = __GLX_PAD(n) >> 2;
reply.type = X_Reply; reply.type = X_Reply;
reply.sequenceNumber = client->sequence; reply.sequenceNumber = client->sequence;
@ -2365,7 +2295,7 @@ int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
buf = (char *) xalloc(length << 2); buf = (char *) xalloc(length << 2);
if (buf == NULL) if (buf == NULL)
return BadAlloc; return BadAlloc;
memcpy(buf, ptr, n); memcpy(buf, pGlxScreen->GLXextensions, n);
if (client->swapped) { if (client->swapped) {
glxSwapQueryExtensionsStringReply(client, &reply, buf); glxSwapQueryExtensionsStringReply(client, &reply, buf);
@ -2383,25 +2313,16 @@ int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc)
ClientPtr client = cl->client; ClientPtr client = cl->client;
xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
xGLXQueryServerStringReply reply; xGLXQueryServerStringReply reply;
int name;
GLuint screen;
size_t n, length; size_t n, length;
const char *ptr; const char *ptr;
char *buf; char *buf;
__GLXscreen *pGlxScreen; __GLXscreen *pGlxScreen;
int err;
name = req->name; if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
screen = req->screen; return err;
/*
** Check if screen exists.
*/
if (screen >= screenInfo.numScreens) {
client->errorValue = screen;
return BadValue;
}
pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
switch(name) { switch(req->name) {
case GLX_VENDOR: case GLX_VENDOR:
ptr = pGlxScreen->GLXvendor; ptr = pGlxScreen->GLXvendor;
break; break;

View File

@ -42,10 +42,6 @@
#include <damage.h> #include <damage.h>
#ifdef XF86DRI
#include <GL/internal/dri_interface.h>
#endif
/* We just need to avoid clashing with DRAWABLE_{WINDOW,PIXMAP} */ /* We just need to avoid clashing with DRAWABLE_{WINDOW,PIXMAP} */
enum { enum {
GLX_DRAWABLE_WINDOW, GLX_DRAWABLE_WINDOW,

View File

@ -658,64 +658,6 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
return &private->base; return &private->base;
} }
static unsigned
filter_modes(__GLcontextModes **server_modes,
const __GLcontextModes *driver_modes)
{
__GLcontextModes * m;
__GLcontextModes ** prev_next;
const __GLcontextModes * check;
unsigned modes_count = 0;
if ( driver_modes == NULL ) {
LogMessage(X_WARNING,
"AIGLX: 3D driver returned no fbconfigs.\n");
return 0;
}
/* For each mode in server_modes, check to see if a matching mode exists
* in driver_modes. If not, then the mode is not available.
*/
prev_next = server_modes;
for ( m = *prev_next ; m != NULL ; m = *prev_next ) {
GLboolean do_delete = GL_TRUE;
for ( check = driver_modes ; check != NULL ; check = check->next ) {
if ( _gl_context_modes_are_same( m, check ) ) {
do_delete = GL_FALSE;
break;
}
}
/* The 3D has to support all the modes that match the GLX visuals
* sent from the X server.
*/
if ( do_delete && (m->visualID != 0) ) {
do_delete = GL_FALSE;
LogMessage(X_WARNING,
"AIGLX: 3D driver claims to not support "
"visual 0x%02x\n", m->visualID);
}
if ( do_delete ) {
*prev_next = m->next;
m->next = NULL;
_gl_context_modes_destroy( m );
}
else {
modes_count++;
prev_next = & m->next;
}
}
return modes_count;
}
static GLboolean static GLboolean
getDrawableInfo(__DRIdrawable *driDrawable, getDrawableInfo(__DRIdrawable *driDrawable,
unsigned int *index, unsigned int *stamp, unsigned int *index, unsigned int *stamp,
@ -923,7 +865,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
char *driverName; char *driverName;
drm_handle_t hFB; drm_handle_t hFB;
int junk; int junk;
__GLcontextModes * driver_modes;
__GLXDRIscreen *screen; __GLXDRIscreen *screen;
void *dev_priv = NULL; void *dev_priv = NULL;
char filename[128]; char filename[128];
@ -1073,7 +1014,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
goto handle_error; goto handle_error;
} }
driver_modes = NULL;
screen->driScreen.private = screen->driScreen.private =
(*createNewScreen)(pScreen->myNum, (*createNewScreen)(pScreen->myNum,
&screen->driScreen, &screen->driScreen,
@ -1085,7 +1025,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
fd, fd,
api_ver, api_ver,
&interface_methods, &interface_methods,
&driver_modes); &screen->base.fbconfigs);
if (screen->driScreen.private == NULL) { if (screen->driScreen.private == NULL) {
LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed"); LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed");
@ -1110,10 +1050,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
screen->base.GLXextensions); screen->base.GLXextensions);
} }
filter_modes(&screen->base.modes, driver_modes);
_gl_context_modes_destroy(driver_modes);
__glXsetEnterLeaveServerFuncs(__glXDRIenterServer, __glXDRIleaveServer); __glXsetEnterLeaveServerFuncs(__glXDRIenterServer, __glXDRIleaveServer);
screen->enterVT = pScrn->EnterVT; screen->enterVT = pScrn->EnterVT;

View File

@ -392,7 +392,7 @@ void glxSuspendClients(void)
int i; int i;
for (i = 1; i < currentMaxClients; i++) { for (i = 1; i < currentMaxClients; i++) {
if (glxGetClient(clients[i])->inUse) if (clients[i] && glxGetClient(clients[i])->inUse)
IgnoreClient(clients[i]); IgnoreClient(clients[i]);
} }
@ -407,7 +407,7 @@ void glxResumeClients(void)
glxBlockClients = FALSE; glxBlockClients = FALSE;
for (i = 1; i < currentMaxClients; i++) { for (i = 1; i < currentMaxClients; i++) {
if (glxGetClient(clients[i])->inUse) if (clients[i] && glxGetClient(clients[i])->inUse)
AttendClient(clients[i]); AttendClient(clients[i]);
} }

View File

@ -70,7 +70,7 @@ struct __GLXMESAdrawable {
XMesaBuffer xm_buf; XMesaBuffer xm_buf;
}; };
static XMesaVisual find_mesa_visual(__GLXscreen *screen, VisualID vid); static XMesaVisual find_mesa_visual(__GLXscreen *screen, XID fbconfigID);
static void static void
@ -141,7 +141,7 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen,
glxPriv->base.resize = __glXMesaDrawableResize; glxPriv->base.resize = __glXMesaDrawableResize;
glxPriv->base.swapBuffers = __glXMesaDrawableSwapBuffers; glxPriv->base.swapBuffers = __glXMesaDrawableSwapBuffers;
xm_vis = find_mesa_visual(screen, modes->visualID); xm_vis = find_mesa_visual(screen, modes->fbconfigID);
if (xm_vis == NULL) { if (xm_vis == NULL) {
ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
modes->visualID); modes->visualID);
@ -155,6 +155,11 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen,
glxPriv->xm_buf = XMesaCreatePixmapBuffer(xm_vis, (PixmapPtr)pDraw, 0); glxPriv->xm_buf = XMesaCreatePixmapBuffer(xm_vis, (PixmapPtr)pDraw, 0);
} }
if (glxPriv->xm_buf == NULL) {
xfree(glxPriv);
return NULL;
}
return &glxPriv->base; return &glxPriv->base;
} }
@ -235,7 +240,7 @@ __glXMesaScreenCreateContext(__GLXscreen *screen,
context->base.copy = __glXMesaContextCopy; context->base.copy = __glXMesaContextCopy;
context->base.forceCurrent = __glXMesaContextForceCurrent; context->base.forceCurrent = __glXMesaContextForceCurrent;
xm_vis = find_mesa_visual(screen, modes->visualID); xm_vis = find_mesa_visual(screen, modes->fbconfigID);
if (!xm_vis) { if (!xm_vis) {
ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
modes->visualID); modes->visualID);
@ -274,107 +279,122 @@ __glXMesaScreenDestroy(__GLXscreen *screen)
} }
static XMesaVisual static XMesaVisual
find_mesa_visual(__GLXscreen *screen, VisualID vid) find_mesa_visual(__GLXscreen *screen, XID fbconfigID)
{ {
__GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen; __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen;
const __GLcontextModes *modes; const __GLcontextModes *modes;
unsigned i = 0; unsigned i = 0;
for ( modes = screen->modes ; modes != NULL ; modes = modes->next ) { for (modes = screen->fbconfigs; modes != NULL; modes = modes->next) {
if ( modes->visualID == vid ) { if (modes->fbconfigID == fbconfigID)
break; return mesaScreen->xm_vis[i];
}
i++; i++;
} }
return (modes != NULL) ? mesaScreen->xm_vis[i] : NULL; return NULL;
} }
static void init_screen_visuals(__GLXMESAscreen *screen) const static int numBack = 2;
const static int numDepth = 2;
const static int numStencil = 2;
static __GLcontextModes *
createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen,
VisualPtr visual, __GLcontextModes *config)
{ {
ScreenPtr pScreen = screen->base.pScreen; int back, depth, stencil;
__GLcontextModes *modes;
XMesaVisual *pXMesaVisual;
int *used;
int num_vis, j, size;
/* Alloc space for the list of XMesa visuals */ /* FIXME: Ok, I'm making all this up... anybody has a better idea? */
size = screen->base.numVisuals * sizeof(XMesaVisual);
pXMesaVisual = (XMesaVisual *) xalloc(size);
memset(pXMesaVisual, 0, size);
/* FIXME: Change 'used' to be a array of bits (rather than of ints), for (back = numBack - 1; back >= 0; back--)
* FIXME: create a stack array of 8 or 16 bytes. If 'numVisuals' is less for (depth = 0; depth < numDepth; depth++)
* FIXME: than 64 or 128 the stack array can be used instead of calling for (stencil = 0; stencil < numStencil; stencil++) {
* FIXME: __glXMalloc / __glXFree. If nothing else, convert 'used' to config->visualType = _gl_convert_from_x_visual_type(visual->class);
* FIXME: array of bytes instead of ints! config->xRenderable = GL_TRUE;
*/ config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
used = (int *) xalloc(pScreen->numVisuals * sizeof(int)); config->rgbMode = (visual->class >= TrueColor);
memset(used, 0, pScreen->numVisuals * sizeof(int)); config->colorIndexMode = !config->rgbMode;
config->renderType =
(config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
config->doubleBufferMode = back;
config->haveDepthBuffer = depth;
config->depthBits = depth ? visual->nplanes : 0;
config->haveStencilBuffer = stencil;
config->stencilBits = stencil ? visual->bitsPerRGBValue : 0;
config->haveAccumBuffer = 0;
num_vis = 0; config->redBits = Ones(visual->redMask);
for ( modes = screen->base.modes; modes != NULL; modes = modes->next ) { config->greenBits = Ones(visual->greenMask);
const int vis_class = _gl_convert_to_x_visual_type( modes->visualType ); config->blueBits = Ones(visual->blueMask);
const int nplanes = (modes->rgbBits - modes->alphaBits); config->alphaBits = 0;
const VisualPtr pVis = pScreen->visuals; config->redMask = visual->redMask;
config->greenMask = visual->greenMask;
config->blueMask = visual->blueMask;
config->alphaMask = 0;
config->rgbBits = config->rgbMode ? visual->nplanes : 0;
config->indexBits = config->colorIndexMode ? visual->nplanes : 0;
config = config->next;
}
for (j = 0; j < pScreen->numVisuals; j++) { return config;
if (pVis[j].class == vis_class && }
pVis[j].nplanes == nplanes &&
pVis[j].redMask == modes->redMask &&
pVis[j].greenMask == modes->greenMask &&
pVis[j].blueMask == modes->blueMask &&
!used[j]) {
/* Create the XMesa visual */ static void
assert(num_vis < screen->base.numVisuals); createFBConfigs(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
pXMesaVisual[num_vis] = {
XMesaCreateVisual(pScreen, __GLcontextModes *configs;
&pVis[j], int i;
modes->rgbMode,
(modes->alphaBits > 0),
modes->doubleBufferMode,
modes->stereoMode,
GL_TRUE, /* ximage_flag */
modes->depthBits,
modes->stencilBits,
modes->accumRedBits,
modes->accumGreenBits,
modes->accumBlueBits,
modes->accumAlphaBits,
modes->samples,
modes->level,
modes->visualRating);
/* Set the VisualID */
modes->visualID = pVis[j].vid;
/* Mark this visual used */ /* We assume here that each existing visual correspond to a
used[j] = 1; * different visual class. Note, this runs before COMPOSITE adds
* its visual, so it's not entirely crazy. */
pGlxScreen->numFBConfigs = pScreen->numVisuals * numBack * numDepth * numStencil;
pGlxScreen->fbconfigs = _gl_context_modes_create(pGlxScreen->numFBConfigs,
sizeof *configs);
configs = pGlxScreen->fbconfigs;
for (i = 0; i < pScreen->numVisuals; i++)
configs = createFBConfigsForVisual(pGlxScreen, pScreen,
&pScreen->visuals[i], configs);
}
static void
createMesaVisuals(__GLXMESAscreen *pMesaScreen)
{
__GLcontextModes *config;
ScreenPtr pScreen;
VisualPtr visual;
int i, j;
i = 0;
pScreen = pMesaScreen->base.pScreen;
pMesaScreen->xm_vis =
xcalloc(pMesaScreen->base.numFBConfigs, sizeof (XMesaVisual));
for (config = pMesaScreen->base.fbconfigs; config != NULL; config = config->next) {
for (j = 0; j < pScreen->numVisuals; j++)
if (pScreen->visuals[j].vid == config->visualID) {
visual = &pScreen->visuals[j];
break; break;
} }
}
if ( j == pScreen->numVisuals ) { pMesaScreen->xm_vis[i++] =
ErrorF("No matching visual for __GLcontextMode with " XMesaCreateVisual(pScreen,
"visual class = %d (%d), nplanes = %u\n", visual,
vis_class, config->rgbMode,
modes->visualType, (config->alphaBits > 0),
(modes->rgbBits - modes->alphaBits) ); config->doubleBufferMode,
} config->stereoMode,
else if ( modes->visualID == -1 ) { GL_TRUE, /* ximage_flag */
FatalError( "Matching visual found, but visualID still -1!\n" ); config->depthBits,
} config->stencilBits,
config->accumRedBits,
num_vis++; config->accumGreenBits,
config->accumBlueBits,
config->accumAlphaBits,
config->samples,
config->level,
config->visualRating);
} }
xfree(used);
screen->num_vis = num_vis;
screen->xm_vis = pXMesaVisual;
assert(screen->num_vis <= screen->base.numVisuals);
} }
static __GLXscreen * static __GLXscreen *
@ -386,19 +406,22 @@ __glXMesaScreenProbe(ScreenPtr pScreen)
if (screen == NULL) if (screen == NULL)
return NULL; return NULL;
/*
* Find the GLX visuals that are supported by this screen and create
* XMesa's visuals.
*/
createFBConfigs(&screen->base, pScreen);
__glXScreenInit(&screen->base, pScreen); __glXScreenInit(&screen->base, pScreen);
/* Now that GLX has created the corresponding X visual, create the mesa visuals. */
createMesaVisuals(screen);
screen->base.destroy = __glXMesaScreenDestroy; screen->base.destroy = __glXMesaScreenDestroy;
screen->base.createContext = __glXMesaScreenCreateContext; screen->base.createContext = __glXMesaScreenCreateContext;
screen->base.createDrawable = __glXMesaScreenCreateDrawable; screen->base.createDrawable = __glXMesaScreenCreateDrawable;
screen->base.pScreen = pScreen; screen->base.pScreen = pScreen;
/*
* Find the GLX visuals that are supported by this screen and create
* XMesa's visuals.
*/
init_screen_visuals(screen);
return &screen->base; return &screen->base;
} }

View File

@ -40,11 +40,13 @@
#include <string.h> #include <string.h>
#include <windowstr.h> #include <windowstr.h>
#include <os.h> #include <os.h>
#include <colormapst.h>
#include "privates.h" #include "privates.h"
#include "glxserver.h" #include "glxserver.h"
#include "glxutil.h" #include "glxutil.h"
#include "glxext.h" #include "glxext.h"
#include "glcontextmodes.h"
static DevPrivateKey glxScreenPrivateKey = &glxScreenPrivateKey; static DevPrivateKey glxScreenPrivateKey = &glxScreenPrivateKey;
@ -282,23 +284,252 @@ glxGetScreen(ScreenPtr pScreen)
return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey); return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey);
} }
void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen) void GlxSetVisualConfigs(int nconfigs,
__GLXvisualConfig *configs, void **privates)
{ {
glxScreen->pScreen = pScreen; /* We keep this stub around for the DDX drivers that still
glxScreen->GLextensions = xstrdup(GLServerExtensions); * call it. */
glxScreen->GLXvendor = xstrdup(GLXServerVendorName); }
glxScreen->GLXversion = xstrdup(GLXServerVersion);
glxScreen->GLXextensions = xstrdup(GLXServerExtensions);
glxScreen->PositionWindow = pScreen->PositionWindow; static XID
findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m)
{
int i;
for (i = 0; i < pScreen->numVisuals; i++) {
if (_gl_convert_to_x_visual_type(m->visualType) == pScreen->visuals[i].class)
return pScreen->visuals[i].vid;
}
return 0;
}
/* This code inspired by composite/compinit.c. We could move this to
* mi/ and share it with composite.*/
static VisualPtr
AddScreenVisuals(ScreenPtr pScreen, int count, int d)
{
XID *installedCmaps, *vids, vid;
int numInstalledCmaps, numVisuals, i, j;
VisualPtr visuals;
ColormapPtr installedCmap;
DepthPtr depth;
depth = NULL;
for (i = 0; i < pScreen->numDepths; i++) {
if (pScreen->allowedDepths[i].depth == d) {
depth = &pScreen->allowedDepths[i];
break;
}
}
if (depth == NULL)
return NULL;
/* Find the installed colormaps */
installedCmaps = xalloc (pScreen->maxInstalledCmaps * sizeof (XID));
if (!installedCmaps)
return NULL;
numInstalledCmaps = pScreen->ListInstalledColormaps(pScreen, installedCmaps);
/* realloc the visual array to fit the new one in place */
numVisuals = pScreen->numVisuals;
visuals = xrealloc(pScreen->visuals, (numVisuals + count) * sizeof(VisualRec));
if (!visuals) {
xfree(installedCmaps);
return NULL;
}
vids = xrealloc(depth->vids, (depth->numVids + count) * sizeof(XID));
if (vids == NULL) {
xfree(installedCmaps);
xfree(visuals);
return NULL;
}
/*
* Fix up any existing installed colormaps -- we'll assume that
* the only ones created so far have been installed. If this
* isn't true, we'll have to walk the resource database looking
* for all colormaps.
*/
for (i = 0; i < numInstalledCmaps; i++) {
installedCmap = LookupIDByType (installedCmaps[i], RT_COLORMAP);
if (!installedCmap)
continue;
j = installedCmap->pVisual - pScreen->visuals;
installedCmap->pVisual = &visuals[j];
}
xfree(installedCmaps);
for (i = 0; i < count; i++) {
vid = FakeClientID(0);
visuals[pScreen->numVisuals + i].vid = vid;
vids[depth->numVids + i] = vid;
}
pScreen->visuals = visuals;
pScreen->numVisuals += count;
depth->vids = vids;
depth->numVids += count;
/* Return a pointer to the first of the added visuals. */
return pScreen->visuals + pScreen->numVisuals - count;
}
static int
findFirstSet(unsigned int v)
{
int i;
for (i = 0; i < 32; i++)
if (v & (1 << i))
return i;
return -1;
}
static void
initGlxVisual(VisualPtr visual, __GLcontextModes *config)
{
config->visualID = visual->vid;
visual->class = _gl_convert_to_x_visual_type(config->visualType);
visual->bitsPerRGBValue = config->redBits;
visual->ColormapEntries = 1 << config->redBits;
visual->nplanes = config->redBits + config->greenBits + config->blueBits;
visual->redMask = config->redMask;
visual->greenMask = config->greenMask;
visual->blueMask = config->blueMask;
visual->offsetRed = findFirstSet(config->redMask);
visual->offsetGreen = findFirstSet(config->greenMask);
visual->offsetBlue = findFirstSet(config->blueMask);
}
static void
addMinimalSet(__GLXscreen *pGlxScreen)
{
__GLcontextModes *config;
VisualPtr visuals;
int depth;
for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
if (config->visualRating != GLX_NONE)
continue;
if (config->doubleBufferMode && config->depthBits > 0)
break;
}
if (config == NULL)
config = pGlxScreen->fbconfigs;
pGlxScreen->visuals = xcalloc(1, sizeof (__GLcontextModes *));
if (pGlxScreen->visuals == NULL) {
ErrorF("Failed to allocate for minimal set of GLX visuals\n");
return;
}
depth = config->redBits + config->greenBits + config->blueBits;
visuals = AddScreenVisuals(pGlxScreen->pScreen, 1, depth);
if (visuals == NULL) {
xfree(pGlxScreen->visuals);
return;
}
pGlxScreen->numVisuals = 1;
pGlxScreen->visuals[0] = config;
initGlxVisual(&visuals[0], config);
}
static void
addTypicalSet(__GLXscreen *pGlxScreen)
{
addMinimalSet(pGlxScreen);
}
static void
addFullSet(__GLXscreen *pGlxScreen)
{
__GLcontextModes *config;
VisualPtr visuals;
int i, depth;
pGlxScreen->visuals =
xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLcontextModes *));
if (pGlxScreen->visuals == NULL) {
ErrorF("Failed to allocate for full set of GLX visuals\n");
return;
}
config = pGlxScreen->fbconfigs;
depth = config->redBits + config->greenBits + config->blueBits;
visuals = AddScreenVisuals(pGlxScreen->pScreen, pGlxScreen->numFBConfigs, depth);
if (visuals == NULL) {
xfree(pGlxScreen->visuals);
return;
}
pGlxScreen->numVisuals = pGlxScreen->numFBConfigs;
for (i = 0, config = pGlxScreen->fbconfigs; config; config = config->next, i++) {
pGlxScreen->visuals[i] = config;
initGlxVisual(&visuals[i], config);
}
}
static int glxVisualConfig = GLX_ALL_VISUALS;
void GlxSetVisualConfig(int config)
{
glxVisualConfig = config;
}
void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
{
__GLcontextModes *m;
int i;
pGlxScreen->pScreen = pScreen;
pGlxScreen->GLextensions = xstrdup(GLServerExtensions);
pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName);
pGlxScreen->GLXversion = xstrdup(GLXServerVersion);
pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions);
pGlxScreen->PositionWindow = pScreen->PositionWindow;
pScreen->PositionWindow = glxPositionWindow; pScreen->PositionWindow = glxPositionWindow;
glxScreen->CloseScreen = pScreen->CloseScreen; pGlxScreen->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = glxCloseScreen; pScreen->CloseScreen = glxCloseScreen;
__glXScreenInitVisuals(glxScreen); i = 0;
for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
m->fbconfigID = FakeClientID(0);
m->visualID = findVisualForConfig(pScreen, m);
ErrorF("mapping fbconfig id 0x%02lx to visual id 0x%02lx\n",
m->fbconfigID, m->visualID);
i++;
}
pGlxScreen->numFBConfigs = i;
dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, glxScreen); /* Select a subset of fbconfigs that we send to the client when it
* asks for the glx visuals. All the fbconfigs here have a valid
* value for visual ID and each visual ID is only present once.
* This runs before composite adds its extra visual so we have to
* remember the number of visuals here.*/
switch (glxVisualConfig) {
case GLX_MINIMAL_VISUALS:
addMinimalSet(pGlxScreen);
break;
case GLX_TYPICAL_VISUALS:
addTypicalSet(pGlxScreen);
break;
case GLX_ALL_VISUALS:
addFullSet(pGlxScreen);
break;
}
dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen);
} }
void __glXScreenDestroy(__GLXscreen *screen) void __glXScreenDestroy(__GLXscreen *screen)

View File

@ -83,14 +83,13 @@ struct __GLXscreen {
ScreenPtr pScreen; ScreenPtr pScreen;
/** /* Linked list of valid fbconfigs for this screen. */
* Linked list of valid context modes for this screen. __GLcontextModes *fbconfigs;
*/ int numFBConfigs;
__GLcontextModes *modes;
void **pVisualPriv; /* Subset of fbconfigs that are exposed as GLX visuals. */
__GLcontextModes **visuals;
GLint numVisuals; GLint numVisuals;
GLint numUsableVisuals;
char *GLextensions; char *GLextensions;

View File

@ -95,6 +95,8 @@ extern __GLXclientState *glxGetClient(ClientPtr pClient);
/************************************************************************/ /************************************************************************/
void GlxExtensionInit(void);
void GlxSetVisualConfigs(int nconfigs, void GlxSetVisualConfigs(int nconfigs,
__GLXvisualConfig *configs, void **privates); __GLXvisualConfig *configs, void **privates);
@ -132,6 +134,14 @@ struct __GLXprovider {
void GlxPushProvider(__GLXprovider *provider); void GlxPushProvider(__GLXprovider *provider);
enum {
GLX_MINIMAL_VISUALS,
GLX_TYPICAL_VISUALS,
GLX_ALL_VISUALS
};
void GlxSetVisualConfig(int config);
void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean), void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean),
void (*leave)(GLboolean)); void (*leave)(GLboolean));
void __glXenterServer(GLboolean rendering); void __glXenterServer(GLboolean rendering);

View File

@ -1,520 +0,0 @@
/*
* Copyright © 2006 Red Hat, Inc.
* (C) Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
* 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, sub license,
* 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 and this permission notice (including the next
* paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
* RED HAT, INC, OR PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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.
*/
/*
* Authors:
* Kevin E. Martin <kevin@precisioninsight.com>
* Brian Paul <brian@precisioninsight.com>
* Kristian Høgsberg <krh@redhat.com>
*
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <assert.h>
#include <string.h>
#include <regionstr.h>
#include <resource.h>
#include <GL/gl.h>
#include <GL/glxint.h>
#include <GL/glxtokens.h>
#include <GL/internal/glcore.h>
#include <scrnintstr.h>
#include <config.h>
#include <glxserver.h>
#include <glxscreens.h>
#include <glxdrawable.h>
#include <glxcontext.h>
#include <glxext.h>
#include <glxutil.h>
#include <micmap.h>
void GlxWrapInitVisuals(miInitVisualsProcPtr *);
extern Bool noGlxVisualInit;
#include "glcontextmodes.h"
struct ScreenVisualsRec {
int num_vis;
void *private;
__GLcontextModes *modes;
};
typedef struct ScreenVisualsRec ScreenVisuals;
static ScreenVisuals screenVisuals[MAXSCREENS];
static int numConfigs = 0;
static __GLXvisualConfig *visualConfigs = NULL;
static void **visualPrivates = NULL;
static int count_bits(unsigned int n)
{
int bits = 0;
while (n > 0) {
if (n & 1) bits++;
n >>= 1;
}
return bits;
}
/*
* In the case the driver defines no GLX visuals we'll use these.
* Note that for TrueColor and DirectColor visuals, bufferSize is the
* sum of redSize, greenSize, blueSize and alphaSize, which may be larger
* than the nplanes/rootDepth of the server's X11 visuals
*/
#define NUM_FALLBACK_CONFIGS 5
static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = {
/* [0] = RGB, double buffered, Z */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
0, 0, 0, 0, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
0, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [1] = RGB, double buffered, Z, stencil, accum */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
16, 16, 16, 0, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
8, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [2] = RGB+Alpha, double buffered, Z, stencil, accum */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 8, /* rgba sizes */
-1, -1, -1, -1, /* rgba masks */
16, 16, 16, 16, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
8, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [3] = RGB+Alpha, single buffered, Z, stencil, accum */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 8, /* rgba sizes */
-1, -1, -1, -1, /* rgba masks */
16, 16, 16, 16, /* rgba accum sizes */
False, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
8, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [4] = CI, double buffered, Z */
{
-1, /* vid */
-1, /* class */
False, /* rgba? (false = color index) */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
0, 0, 0, 0, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
0, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
};
static Bool init_visuals(int *nvisualp, VisualPtr *visualp,
VisualID *defaultVisp,
int ndepth, DepthPtr pdepth,
int rootDepth)
{
int numRGBconfigs;
int numCIconfigs;
int numVisuals = *nvisualp;
int numNewVisuals;
int numNewConfigs;
VisualPtr pVisual = *visualp;
VisualPtr pVisualNew = NULL;
VisualID *orig_vid = NULL;
__GLcontextModes *modes;
__GLXvisualConfig *pNewVisualConfigs = NULL;
void **glXVisualPriv;
void **pNewVisualPriv;
int found_default;
int i, j, k;
if (numConfigs > 0)
numNewConfigs = numConfigs;
else
numNewConfigs = NUM_FALLBACK_CONFIGS;
/* Alloc space for the list of new GLX visuals */
pNewVisualConfigs = (__GLXvisualConfig *)
xalloc(numNewConfigs * sizeof(__GLXvisualConfig));
if (!pNewVisualConfigs) {
return FALSE;
}
/* Alloc space for the list of new GLX visual privates */
pNewVisualPriv = (void **) xalloc(numNewConfigs * sizeof(void *));
if (!pNewVisualPriv) {
xfree(pNewVisualConfigs);
return FALSE;
}
/*
** If SetVisualConfigs was not called, then use default GLX
** visual configs.
*/
if (numConfigs == 0) {
memcpy(pNewVisualConfigs, FallbackConfigs,
NUM_FALLBACK_CONFIGS * sizeof(__GLXvisualConfig));
memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *));
}
else {
/* copy driver's visual config info */
for (i = 0; i < numConfigs; i++) {
pNewVisualConfigs[i] = visualConfigs[i];
pNewVisualPriv[i] = visualPrivates[i];
}
}
/* Count the number of RGB and CI visual configs */
numRGBconfigs = 0;
numCIconfigs = 0;
for (i = 0; i < numNewConfigs; i++) {
if (pNewVisualConfigs[i].rgba)
numRGBconfigs++;
else
numCIconfigs++;
}
/* Count the total number of visuals to compute */
numNewVisuals = 0;
for (i = 0; i < numVisuals; i++) {
numNewVisuals +=
(pVisual[i].class == TrueColor || pVisual[i].class == DirectColor)
? numRGBconfigs : numCIconfigs;
}
/* Reset variables for use with the next screen/driver's visual configs */
visualConfigs = NULL;
numConfigs = 0;
/* Alloc temp space for the list of orig VisualIDs for each new visual */
orig_vid = (VisualID *) xalloc(numNewVisuals * sizeof(VisualID));
if (!orig_vid) {
xfree(pNewVisualPriv);
xfree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the list of glXVisuals */
modes = _gl_context_modes_create(numNewVisuals, sizeof(__GLcontextModes));
if (modes == NULL) {
xfree(orig_vid);
xfree(pNewVisualPriv);
xfree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the list of glXVisualPrivates */
glXVisualPriv = (void **)xalloc(numNewVisuals * sizeof(void *));
if (!glXVisualPriv) {
_gl_context_modes_destroy( modes );
xfree(orig_vid);
xfree(pNewVisualPriv);
xfree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the new list of the X server's visuals */
pVisualNew = (VisualPtr)xalloc(numNewVisuals * sizeof(VisualRec));
if (!pVisualNew) {
xfree(glXVisualPriv);
_gl_context_modes_destroy( modes );
xfree(orig_vid);
xfree(pNewVisualPriv);
xfree(pNewVisualConfigs);
return FALSE;
}
/* Initialize the new visuals */
found_default = FALSE;
screenVisuals[screenInfo.numScreens-1].modes = modes;
for (i = j = 0; i < numVisuals; i++) {
int is_rgb = (pVisual[i].class == TrueColor ||
pVisual[i].class == DirectColor);
for (k = 0; k < numNewConfigs; k++) {
if (pNewVisualConfigs[k].rgba != is_rgb)
continue;
assert( modes != NULL );
/* Initialize the new visual */
pVisualNew[j] = pVisual[i];
pVisualNew[j].vid = FakeClientID(0);
/* Check for the default visual */
if (!found_default && pVisual[i].vid == *defaultVisp) {
*defaultVisp = pVisualNew[j].vid;
found_default = TRUE;
}
/* Save the old VisualID */
orig_vid[j] = pVisual[i].vid;
/* Initialize the glXVisual */
_gl_copy_visual_to_context_mode( modes, & pNewVisualConfigs[k] );
modes->visualID = pVisualNew[j].vid;
if (modes->fbconfigID == GLX_DONT_CARE)
modes->fbconfigID = modes->visualID;
/*
* If the class is -1, then assume the X visual information
* is identical to what GLX needs, and take them from the X
* visual. NOTE: if class != -1, then all other fields MUST
* be initialized.
*/
if (modes->visualType == GLX_NONE) {
modes->visualType = _gl_convert_from_x_visual_type( pVisual[i].class );
modes->redBits = count_bits(pVisual[i].redMask);
modes->greenBits = count_bits(pVisual[i].greenMask);
modes->blueBits = count_bits(pVisual[i].blueMask);
modes->alphaBits = modes->alphaBits;
modes->redMask = pVisual[i].redMask;
modes->greenMask = pVisual[i].greenMask;
modes->blueMask = pVisual[i].blueMask;
modes->alphaMask = modes->alphaMask;
modes->rgbBits = (is_rgb)
? (modes->redBits + modes->greenBits +
modes->blueBits + modes->alphaBits)
: rootDepth;
}
/* Save the device-dependent private for this visual */
glXVisualPriv[j] = pNewVisualPriv[k];
j++;
modes = modes->next;
}
}
assert(j <= numNewVisuals);
/* Save the GLX visuals in the screen structure */
screenVisuals[screenInfo.numScreens-1].num_vis = numNewVisuals;
screenVisuals[screenInfo.numScreens-1].private = glXVisualPriv;
/* Set up depth's VisualIDs */
for (i = 0; i < ndepth; i++) {
int numVids = 0;
VisualID *pVids = NULL;
int k, n = 0;
/* Count the new number of VisualIDs at this depth */
for (j = 0; j < pdepth[i].numVids; j++)
for (k = 0; k < numNewVisuals; k++)
if (pdepth[i].vids[j] == orig_vid[k])
numVids++;
/* Allocate a new list of VisualIDs for this depth */
pVids = (VisualID *)xalloc(numVids * sizeof(VisualID));
/* Initialize the new list of VisualIDs for this depth */
for (j = 0; j < pdepth[i].numVids; j++)
for (k = 0; k < numNewVisuals; k++)
if (pdepth[i].vids[j] == orig_vid[k])
pVids[n++] = pVisualNew[k].vid;
/* Update this depth's list of VisualIDs */
xfree(pdepth[i].vids);
pdepth[i].vids = pVids;
pdepth[i].numVids = numVids;
}
/* Update the X server's visuals */
*nvisualp = numNewVisuals;
*visualp = pVisualNew;
/* Free the old list of the X server's visuals */
xfree(pVisual);
/* Clean up temporary allocations */
xfree(orig_vid);
xfree(pNewVisualPriv);
xfree(pNewVisualConfigs);
/* Free the private list created by DDX HW driver */
if (visualPrivates)
xfree(visualPrivates);
visualPrivates = NULL;
return TRUE;
}
void GlxSetVisualConfigs(int nconfigs,
__GLXvisualConfig *configs, void **privates)
{
numConfigs = nconfigs;
visualConfigs = configs;
visualPrivates = privates;
}
static miInitVisualsProcPtr saveInitVisualsProc;
Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
int *nvisualp, int *ndepthp,
int *rootDepthp, VisualID *defaultVisp,
unsigned long sizes, int bitsPerRGB,
int preferredVis)
{
Bool ret;
if (saveInitVisualsProc) {
ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
rootDepthp, defaultVisp, sizes, bitsPerRGB,
preferredVis);
if (!ret)
return False;
}
/*
* Setup the visuals supported by this particular screen.
*/
if (!noGlxVisualInit) {
init_visuals(nvisualp, visualp, defaultVisp,
*ndepthp, *depthp, *rootDepthp);
}
return True;
}
/************************************************************************/
void
GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
{
saveInitVisualsProc = *initVisProc;
*initVisProc = GlxInitVisuals;
}
static void fixup_visuals(int screen)
{
ScreenPtr pScreen = screenInfo.screens[screen];
ScreenVisuals *psv = &screenVisuals[screen];
int j;
__GLcontextModes *modes;
for ( modes = psv->modes ; modes != NULL ; modes = modes->next ) {
const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
const int nplanes = (modes->rgbBits - modes->alphaBits);
const VisualPtr pVis = pScreen->visuals;
/* Find a visual that matches the GLX visual's class and size */
for (j = 0; j < pScreen->numVisuals; j++) {
if (pVis[j].class == vis_class &&
pVis[j].nplanes == nplanes) {
/* Fixup the masks */
modes->redMask = pVis[j].redMask;
modes->greenMask = pVis[j].greenMask;
modes->blueMask = pVis[j].blueMask;
/* Recalc the sizes */
modes->redBits = count_bits(modes->redMask);
modes->greenBits = count_bits(modes->greenMask);
modes->blueBits = count_bits(modes->blueMask);
}
}
}
}
void __glXScreenInitVisuals(__GLXscreen *screen)
{
int index = screen->pScreen->myNum;
screen->modes = screenVisuals[index].modes;
screen->pVisualPriv = screenVisuals[index].private;
screen->numVisuals = screenVisuals[index].num_vis;
screen->numUsableVisuals = screenVisuals[index].num_vis;
/*
* The ordering of the rgb compenents might have been changed by the
* driver after mi initialized them.
*/
fixup_visuals(index);
}

View File

@ -464,6 +464,10 @@ APPLE_APPLICATIONS_DIR="${bindir}/Applications"
AC_ARG_WITH(apple-applications-dir,AS_HELP_STRING([--with-apple-applications-dir=PATH], [Path to the Applications directory (default: ${bindir}/Applications)]), AC_ARG_WITH(apple-applications-dir,AS_HELP_STRING([--with-apple-applications-dir=PATH], [Path to the Applications directory (default: ${bindir}/Applications)]),
[ APPLE_APPLICATIONS_DIR="${withval}" ]. [ APPLE_APPLICATIONS_DIR="${withval}" ].
[ APPLE_APPLICATIONS_DIR="${bindir}/Applications" ]) [ APPLE_APPLICATIONS_DIR="${bindir}/Applications" ])
AC_ARG_WITH(pci-txt-ids-dir, AS_HELP_STRING([--with-pci-txt-ids-dir=PATH],
[Path to pci id directory (default: ${datadir}/X11/pci)]),
[ PCI_TXT_IDS_DIR="$withval" ],
[ PCI_TXT_IDS_DIR="${datadir}/X11/pci" ])
AC_ARG_ENABLE(builddocs, AS_HELP_STRING([--enable-builddocs], [Build docs (default: disabled)]), AC_ARG_ENABLE(builddocs, AS_HELP_STRING([--enable-builddocs], [Build docs (default: disabled)]),
[BUILDDOCS=$enableval], [BUILDDOCS=$enableval],
[BUILDDOCS=no]) [BUILDDOCS=no])
@ -1022,6 +1026,7 @@ fi
AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path]) AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path])
AC_DEFINE_DIR(RGB_DB, RGBPATH, [Default RGB path]) AC_DEFINE_DIR(RGB_DB, RGBPATH, [Default RGB path])
AC_DEFINE_DIR(PCI_TXT_IDS_PATH, PCI_TXT_IDS_DIR, [Default PCI text file ID path])
AC_DEFINE_DIR(SERVERCONFIGdir, SERVERCONFIG, [Server config path]) AC_DEFINE_DIR(SERVERCONFIGdir, SERVERCONFIG, [Server config path])
AC_DEFINE_DIR(BASE_FONT_PATH, FONTDIR, [Default base font path]) AC_DEFINE_DIR(BASE_FONT_PATH, FONTDIR, [Default base font path])
AC_DEFINE_DIR(DRI_DRIVER_PATH, DRI_DRIVER_PATH, [Default DRI driver path]) AC_DEFINE_DIR(DRI_DRIVER_PATH, DRI_DRIVER_PATH, [Default DRI driver path])
@ -1101,7 +1106,7 @@ PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
# #
XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}" XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}"
XSERVER_LIBS="$DIX_LIB $CONFIG_LIB $MI_LIB $OS_LIB" XSERVER_LIBS="$DIX_LIB $CONFIG_LIB $MI_LIB $OS_LIB"
XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}" XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS} -lcrypto"
AC_SUBST([XSERVER_LIBS]) AC_SUBST([XSERVER_LIBS])
AC_SUBST([XSERVER_SYS_LIBS]) AC_SUBST([XSERVER_SYS_LIBS])
@ -1902,7 +1907,7 @@ if test "$KDRIVE" = yes; then
KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB" KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB"
KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB"
KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS $XV_LIBS" KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $XV_LIBS"
# check if we can build Xephyr # check if we can build Xephyr
PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"]) PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"])

View File

@ -290,7 +290,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
pExaPixmap->fb_ptr = NULL; pExaPixmap->fb_ptr = NULL;
} else { } else {
pExaPixmap->driverPriv = NULL; pExaPixmap->driverPriv = NULL;
/* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */ /* Scratch pixmaps may have w/h equal to zero, and may not be
* migrated.
*/
if (!w || !h) if (!w || !h)
pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
else else
@ -695,7 +697,6 @@ exaCloseScreen(int i, ScreenPtr pScreen)
#ifdef RENDER #ifdef RENDER
if (ps) { if (ps) {
ps->Composite = pExaScr->SavedComposite; ps->Composite = pExaScr->SavedComposite;
ps->Glyphs = pExaScr->SavedGlyphs;
ps->Trapezoids = pExaScr->SavedTrapezoids; ps->Trapezoids = pExaScr->SavedTrapezoids;
} }
#endif #endif
@ -858,9 +859,6 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->SavedTriangles = ps->Triangles; pExaScr->SavedTriangles = ps->Triangles;
ps->Triangles = exaTriangles; ps->Triangles = exaTriangles;
pExaScr->SavedGlyphs = ps->Glyphs;
ps->Glyphs = exaGlyphs;
pExaScr->SavedTrapezoids = ps->Trapezoids; pExaScr->SavedTrapezoids = ps->Trapezoids;
ps->Trapezoids = exaTrapezoids; ps->Trapezoids = exaTrapezoids;
} }

View File

@ -152,6 +152,9 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
int bpp = pDrawable->bitsPerPixel; int bpp = pDrawable->bitsPerPixel;
Bool access_prepared = FALSE; Bool access_prepared = FALSE;
if (pExaPixmap->accel_blocked)
return FALSE;
/* Don't bother with under 8bpp, XYPixmaps. */ /* Don't bother with under 8bpp, XYPixmaps. */
if (format != ZPixmap || bpp < 8) if (format != ZPixmap || bpp < 8)
return FALSE; return FALSE;
@ -655,7 +658,7 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
x1 = ppt[0].x; x1 = ppt[0].x;
y1 = ppt[0].y; y1 = ppt[0].y;
/* If we have any non-horizontal/vertical, fall back. */ /* If we have any non-horizontal/vertical, fall back. */
for (i = 0; i < npt; i++) { for (i = 0; i < npt - 1; i++) {
if (mode == CoordModePrevious) { if (mode == CoordModePrevious) {
x2 = x1 + ppt[i + 1].x; x2 = x1 + ppt[i + 1].x;
y2 = y1 + ppt[i + 1].y; y2 = y1 + ppt[i + 1].y;

View File

@ -299,6 +299,9 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate)
if (pPixmap->drawable.bitsPerPixel < 8) if (pPixmap->drawable.bitsPerPixel < 8)
return; return;
if (pExaPixmap->accel_blocked)
return;
if (pExaPixmap->area == NULL) { if (pExaPixmap->area == NULL) {
pExaPixmap->area = pExaPixmap->area =
exaOffscreenAlloc (pScreen, pExaPixmap->fb_size, exaOffscreenAlloc (pScreen, pExaPixmap->fb_size,

View File

@ -53,6 +53,7 @@
#include "fboverlay.h" #include "fboverlay.h"
#ifdef RENDER #ifdef RENDER
#include "fbpict.h" #include "fbpict.h"
#include "glyphstr.h"
#endif #endif
#include "damage.h" #include "damage.h"

View File

@ -247,10 +247,24 @@ exaTryDriverSolidFill(PicturePtr pSrc,
int nbox; int nbox;
int dst_off_x, dst_off_y; int dst_off_x, dst_off_y;
PixmapPtr pSrcPix, pDstPix; PixmapPtr pSrcPix, pDstPix;
ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
CARD32 pixel; CARD32 pixel;
CARD16 red, green, blue, alpha; CARD16 red, green, blue, alpha;
ExaMigrationRec pixmaps[1]; ExaMigrationRec pixmaps[1];
pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
pDstExaPix = ExaGetPixmapPriv(pDstPix);
/* Check whether the accelerator can use these pixmaps.
*/
if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked)
{
return -1;
}
xDst += pDst->pDrawable->x; xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y; yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x; xSrc += pSrc->pDrawable->x;
@ -261,12 +275,10 @@ exaTryDriverSolidFill(PicturePtr pSrc,
width, height)) width, height))
return 1; return 1;
pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
REGION_TRANSLATE(pScreen, &region, dst_off_x, dst_off_y); REGION_TRANSLATE(pScreen, &region, dst_off_x, dst_off_y);
pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
pixel = exaGetPixmapFirstPixel (pSrcPix); pixel = exaGetPixmapFirstPixel (pSrcPix);
pixmaps[0].as_dst = TRUE; pixmaps[0].as_dst = TRUE;
@ -985,355 +997,3 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
exaTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris); exaTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
} }
} }
/**
* Returns TRUE if the glyphs in the lists intersect. Only checks based on
* bounding box, which appears to be good enough to catch most cases at least.
*/
static Bool
exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
{
int x1, x2, y1, y2;
int n;
GlyphPtr glyph;
int x, y;
BoxRec extents;
Bool first = TRUE;
x = 0;
y = 0;
while (nlist--) {
x += list->xOff;
y += list->yOff;
n = list->len;
list++;
while (n--) {
glyph = *glyphs++;
if (glyph->info.width == 0 || glyph->info.height == 0) {
x += glyph->info.xOff;
y += glyph->info.yOff;
continue;
}
x1 = x - glyph->info.x;
if (x1 < MINSHORT)
x1 = MINSHORT;
y1 = y - glyph->info.y;
if (y1 < MINSHORT)
y1 = MINSHORT;
x2 = x1 + glyph->info.width;
if (x2 > MAXSHORT)
x2 = MAXSHORT;
y2 = y1 + glyph->info.height;
if (y2 > MAXSHORT)
y2 = MAXSHORT;
if (first) {
extents.x1 = x1;
extents.y1 = y1;
extents.x2 = x2;
extents.y2 = y2;
first = FALSE;
} else {
if (x1 < extents.x2 && x2 > extents.x1 &&
y1 < extents.y2 && y2 > extents.y1)
{
return TRUE;
}
if (x1 < extents.x1)
extents.x1 = x1;
if (x2 > extents.x2)
extents.x2 = x2;
if (y1 < extents.y1)
extents.y1 = y1;
if (y2 > extents.y2)
extents.y2 = y2;
}
x += glyph->info.xOff;
y += glyph->info.yOff;
}
}
return FALSE;
}
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The
* issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to
* migrate these pixmaps. So, instead we create a pixmap at the beginning of
* the loop and upload each glyph into the pixmap before compositing.
*
* This is now used even when Composite can't be accelerated for better
* migration control.
*/
void
exaGlyphs (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nlist,
GlyphListPtr list,
GlyphPtr *glyphs)
{
ExaScreenPriv (pDst->pDrawable->pScreen);
PixmapPtr pPixmap = NULL;
PicturePtr pPicture;
PixmapPtr pMaskPixmap = NULL;
PicturePtr pMask;
ScreenPtr pScreen = pDst->pDrawable->pScreen;
int width = 0, height = 0;
int x, y, x1, y1;
int xDst = list->xOff, yDst = list->yOff;
int n;
int error;
BoxRec extents;
CARD32 component_alpha;
/* If we have a mask format but it's the same as all the glyphs and
* the glyphs don't intersect, we can avoid accumulating the glyphs in the
* temporary picture.
*/
if (maskFormat != NULL) {
Bool sameFormat = TRUE;
int i;
for (i = 0; i < nlist; i++) {
if (maskFormat->format != list[i].format->format) {
sameFormat = FALSE;
break;
}
}
if (sameFormat) {
if (!exaGlyphsIntersect(nlist, list, glyphs)) {
maskFormat = NULL;
}
}
}
if (maskFormat)
{
GCPtr pGC;
xRectangle rect;
miGlyphExtents (nlist, list, glyphs, &extents);
extents.x1 = max(extents.x1, 0);
extents.y1 = max(extents.y1, 0);
extents.x2 = min(extents.x2, pDst->pDrawable->width);
extents.y2 = min(extents.y2, pDst->pDrawable->height);
if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
return;
width = extents.x2 - extents.x1;
height = extents.y2 - extents.y1;
pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
maskFormat->depth);
if (!pMaskPixmap)
return;
component_alpha = NeedsComponent(maskFormat->format);
pMask = CreatePicture (0, &pMaskPixmap->drawable,
maskFormat, CPComponentAlpha, &component_alpha,
serverClient, &error);
if (!pMask)
{
(*pScreen->DestroyPixmap) (pMaskPixmap);
return;
}
ValidatePicture(pMask);
pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
ValidateGC (&pMaskPixmap->drawable, pGC);
rect.x = 0;
rect.y = 0;
rect.width = width;
rect.height = height;
ExaCheckPolyFillRect (&pMaskPixmap->drawable, pGC, 1, &rect);
if (pExaScr->info->PrepareComposite)
(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
else
exaPixmapDirty(pMaskPixmap, 0, 0, width, height);
FreeScratchGC (pGC);
x = -extents.x1;
y = -extents.y1;
}
else
{
pMask = pDst;
x = 0;
y = 0;
}
while (nlist--)
{
GCPtr pGC = NULL;
int maxwidth = 0, maxheight = 0, i;
ExaMigrationRec pixmaps[1];
PixmapPtr pScratchPixmap = NULL;
x += list->xOff;
y += list->yOff;
n = list->len;
for (i = 0; i < n; i++) {
if (glyphs[i]->info.width > maxwidth)
maxwidth = glyphs[i]->info.width;
if (glyphs[i]->info.height > maxheight)
maxheight = glyphs[i]->info.height;
}
if (maxwidth == 0 || maxheight == 0) {
while (n--)
{
GlyphPtr glyph;
glyph = *glyphs++;
x += glyph->info.xOff;
y += glyph->info.yOff;
}
list++;
continue;
}
/* Create the (real) temporary pixmap to store the current glyph in */
pPixmap = (*pScreen->CreatePixmap) (pScreen, maxwidth, maxheight,
list->format->depth);
if (!pPixmap)
return;
/* Create a temporary picture to wrap the temporary pixmap, so it can be
* used as a source for Composite.
*/
component_alpha = NeedsComponent(list->format->format);
pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
CPComponentAlpha, &component_alpha,
serverClient, &error);
if (!pPicture) {
(*pScreen->DestroyPixmap) (pPixmap);
return;
}
ValidatePicture(pPicture);
/* Give the temporary pixmap an initial kick towards the screen, so
* it'll stick there.
*/
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap;
pixmaps[0].pReg = NULL;
exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL);
while (n--)
{
GlyphPtr glyph = *glyphs++;
pointer glyphdata = (pointer) (glyph + 1);
DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable;
x1 = x - glyph->info.x;
y1 = y - glyph->info.y;
if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height ||
(x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
goto nextglyph;
(*pScreen->ModifyPixmapHeader) (pScratchPixmap,
glyph->info.width,
glyph->info.height,
0, 0, -1, glyphdata);
/* Copy the glyph data into the proper pixmap instead of a fake.
* First we try to use UploadToScreen, if we can, then we fall back
* to a plain exaCopyArea in case of failure.
*/
if (pExaScr->info->UploadToScreen &&
exaPixmapIsOffscreen(pPixmap) &&
(*pExaScr->info->UploadToScreen) (pPixmap, 0, 0,
glyph->info.width,
glyph->info.height,
glyphdata,
PixmapBytePad(glyph->info.width,
list->format->depth)))
{
exaMarkSync (pScreen);
} else {
/* Set up the scratch pixmap/GC for doing a CopyArea. */
if (pScratchPixmap == NULL) {
/* Get a scratch pixmap to wrap the original glyph data */
pScratchPixmap = GetScratchPixmapHeader (pScreen,
glyph->info.width,
glyph->info.height,
list->format->depth,
list->format->depth,
-1, glyphdata);
if (!pScratchPixmap) {
FreePicture(pPicture, 0);
(*pScreen->DestroyPixmap) (pPixmap);
return;
}
/* Get a scratch GC with which to copy the glyph data from
* scratch to temporary
*/
pGC = GetScratchGC (list->format->depth, pScreen);
ValidateGC (&pPixmap->drawable, pGC);
} else {
(*pScreen->ModifyPixmapHeader) (pScratchPixmap,
glyph->info.width,
glyph->info.height,
0, 0, -1, glyphdata);
pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
#ifdef MITSHM
if (pExaScr->info->PrepareComposite)
exaShmPutImage(&pPixmap->drawable, pGC,
pPixmap->drawable.depth, ZPixmap,
glyph->info.width, glyph->info.height, 0, 0,
glyph->info.width, glyph->info.height, 0, 0,
glyphdata);
else
#endif
exaCopyArea (&pScratchPixmap->drawable, &pPixmap->drawable, pGC,
0, 0, glyph->info.width, glyph->info.height, 0, 0);
}
exaPixmapDirty (pPixmap, 0, 0,
glyph->info.width, glyph->info.height);
if (maskFormat)
{
exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0,
x1, y1, glyph->info.width, glyph->info.height);
exaPixmapDirty(pMaskPixmap, x1, y1, x1 + glyph->info.width,
y1 + glyph->info.height);
}
else
{
exaComposite (op, pSrc, pPicture, pDst,
xSrc + x1 - xDst, ySrc + y1 - yDst,
0, 0, x1, y1, glyph->info.width,
glyph->info.height);
}
nextglyph:
x += glyph->info.xOff;
y += glyph->info.yOff;
}
list++;
if (pGC != NULL)
FreeScratchGC (pGC);
FreePicture ((pointer) pPicture, 0);
(*pScreen->DestroyPixmap) (pPixmap);
if (pScratchPixmap != NULL)
FreeScratchPixmapHeader (pScratchPixmap);
}
if (maskFormat)
{
x = extents.x1;
y = extents.y1;
exaComposite (op, pSrc, pMask, pDst, xSrc + x - xDst, ySrc + y - yDst,
0, 0, x, y, width, height);
FreePicture ((pointer) pMask, (XID) 0);
(*pScreen->DestroyPixmap) (pMaskPixmap);
}
}

View File

@ -329,6 +329,11 @@ autoConfigDevice(GDevPtr preconf_device)
return ptr; return ptr;
} }
#ifdef __linux__
/* This function is used to provide a workaround for binary drivers that
* don't export their PCI ID's properly. If distros don't end up using this
* feature it can and should be removed because the symbol-based resolution
* scheme should be the primary one */
static void static void
matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip) matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip)
{ {
@ -341,9 +346,10 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip
char path_name[256], vendor_str[5], chip_str[5]; char path_name[256], vendor_str[5], chip_str[5];
uint16_t vendor, chip; uint16_t vendor, chip;
int i, j; int i, j;
idsdir = opendir("/usr/share/xserver-xorg/pci");
idsdir = opendir(PCI_TXT_IDS_PATH);
if (idsdir) { if (idsdir) {
xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCI_TXT_IDS_PATH);
direntry = readdir(idsdir); direntry = readdir(idsdir);
/* Read the directory */ /* Read the directory */
while (direntry) { while (direntry) {
@ -355,15 +361,20 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip
/* A tiny bit of sanity checking. We should probably do better */ /* A tiny bit of sanity checking. We should probably do better */
if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) { if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) {
/* We need the full path name to open the file */ /* We need the full path name to open the file */
strncpy(path_name, "/usr/share/xserver-xorg/pci/", 256); strncpy(path_name, PCI_TXT_IDS_PATH, 256);
strncat(path_name, direntry->d_name, (256 - strlen(path_name))); strncat(path_name, "/", 1);
strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1));
fp = fopen(path_name, "r"); fp = fopen(path_name, "r");
if (fp == NULL) { if (fp == NULL) {
xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name); xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name);
goto end; goto end;
} }
/* Read the file */ /* Read the file */
#ifdef __GLIBC__
while ((read = getline(&line, &len, fp)) != -1) { while ((read = getline(&line, &len, fp)) != -1) {
#else
while ((line = fgetln(fp, &len)) != (char *)NULL) {
#endif /* __GLIBC __ */
xchomp(line); xchomp(line);
if (isdigit(line[0])) { if (isdigit(line[0])) {
strncpy(vendor_str, line, 4); strncpy(vendor_str, line, 4);
@ -405,8 +416,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip
matches[i][j] = direntry->d_name[j]; matches[i][j] = direntry->d_name[j];
} }
} }
xf86Msg(X_INFO, "Matched %s from file name %s in autoconfig\n", matches[i], direntry->d_name); xf86Msg(X_INFO, "Matched %s from file name %s\n", matches[i], direntry->d_name);
} }
} else { } else {
/* TODO Handle driver overrides here */ /* TODO Handle driver overrides here */
@ -421,6 +431,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip
xfree(line); xfree(line);
closedir(idsdir); closedir(idsdir);
} }
#endif /* __linux__ */
char* char*
chooseVideoDriver(void) chooseVideoDriver(void)
@ -448,24 +459,27 @@ chooseVideoDriver(void)
ErrorF("Primary device is not PCI\n"); ErrorF("Primary device is not PCI\n");
} }
#ifdef __linux__
matchDriverFromFiles(matches, info->vendor_id, info->device_id); matchDriverFromFiles(matches, info->vendor_id, info->device_id);
#endif /* __linux__ */
/* TODO Handle multiple drivers claiming to support the same PCI ID */ /* TODO Handle multiple drivers claiming to support the same PCI ID */
if (matches[0]) { if (matches[0]) {
chosen_driver = matches[0]; chosen_driver = matches[0];
} else { } else {
chosen_driver = videoPtrToDriverName(info); if (info != NULL)
#if 0 /* Save for later */ chosen_driver = videoPtrToDriverName(info);
#if defined __i386__ || defined __amd64__ || defined __hurd__ if (chosen_driver == NULL) {
chosen_driver = "vesa"; #if defined __i386__ || defined __amd64__ || defined __hurd__
#elif defined __alpha__ chosen_driver = "vesa";
chosen_driver = "vga"; #elif defined __alpha__
#elif defined __sparc__ chosen_driver = "vga";
chosen_driver = "sunffb"; #elif defined __sparc__
#else chosen_driver = "sunffb";
chosen_driver = "fbdev"; #else
#endif chosen_driver = "fbdev";
#endif #endif
}
} }
xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver); xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver);

View File

@ -792,6 +792,7 @@ typedef enum {
FLAG_USE_DEFAULT_FONT_PATH, FLAG_USE_DEFAULT_FONT_PATH,
FLAG_AUTO_ADD_DEVICES, FLAG_AUTO_ADD_DEVICES,
FLAG_AUTO_ENABLE_DEVICES, FLAG_AUTO_ENABLE_DEVICES,
FLAG_GLX_VISUALS,
} FlagValues; } FlagValues;
static OptionInfoRec FlagOptions[] = { static OptionInfoRec FlagOptions[] = {
@ -873,6 +874,8 @@ static OptionInfoRec FlagOptions[] = {
{0}, TRUE }, {0}, TRUE },
{ FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN, { FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN,
{0}, TRUE }, {0}, TRUE },
{ FLAG_GLX_VISUALS, "GlxVisuals", OPTV_STRING,
{0}, FALSE },
{ -1, NULL, OPTV_NONE, { -1, NULL, OPTV_NONE,
{0}, FALSE }, {0}, FALSE },
}; };
@ -904,6 +907,7 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
Pix24Flags pix24 = Pix24DontCare; Pix24Flags pix24 = Pix24DontCare;
Bool value; Bool value;
MessageType from; MessageType from;
const char *s;
/* /*
* Merge the ServerLayout and ServerFlags options. The former have * Merge the ServerLayout and ServerFlags options. The former have
@ -1021,7 +1025,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value)) if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value))
xf86Info.pmFlag = !value; xf86Info.pmFlag = !value;
{ {
const char *s;
if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) { if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
if (!xf86NameCmp(s,"flush")) { if (!xf86NameCmp(s,"flush")) {
xf86Msg(X_CONFIG, "Flushing logfile enabled\n"); xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
@ -1040,8 +1043,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
#ifdef RENDER #ifdef RENDER
{ {
const char *s;
if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){ if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){
int policy = PictureParseCmapPolicy (s); int policy = PictureParseCmapPolicy (s);
if (policy == PictureCmapPolicyInvalid) if (policy == PictureCmapPolicyInvalid)
@ -1055,7 +1056,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
} }
#endif #endif
{ {
const char *s;
if ((s = xf86GetOptValString(FlagOptions, FLAG_HANDLE_SPECIAL_KEYS))) { if ((s = xf86GetOptValString(FlagOptions, FLAG_HANDLE_SPECIAL_KEYS))) {
if (!xf86NameCmp(s,"always")) { if (!xf86NameCmp(s,"always")) {
xf86Msg(X_CONFIG, "Always handling special keys in DDX\n"); xf86Msg(X_CONFIG, "Always handling special keys in DDX\n");
@ -1093,6 +1093,27 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
xf86Info.aiglxFrom = X_CONFIG; xf86Info.aiglxFrom = X_CONFIG;
} }
#ifdef GLXEXT
xf86Info.glxVisuals = XF86_GlxVisualsAll;
xf86Info.glxVisualsFrom = X_DEFAULT;
if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
if (!xf86NameCmp(s, "minimal")) {
xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
} else if (!xf86NameCmp(s, "typical")) {
xf86Info.glxVisuals = XF86_GlxVisualsTypical;
} else if (!xf86NameCmp(s, "all")) {
xf86Info.glxVisuals = XF86_GlxVisualsAll;
} else {
xf86Msg(X_WARNING,"Unknown HandleSpecialKeys option\n");
}
}
if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
xf86Info.aiglx = value;
xf86Info.aiglxFrom = X_CONFIG;
}
#endif
xf86Info.allowEmptyInput = FALSE; xf86Info.allowEmptyInput = FALSE;
if (xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &value)) if (xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &value))
xf86Info.allowEmptyInput = TRUE; xf86Info.allowEmptyInput = TRUE;

View File

@ -60,6 +60,12 @@ typedef enum {
SKAlways SKAlways
} SpecialKeysInDDX; } SpecialKeysInDDX;
typedef enum {
XF86_GlxVisualsMinimal,
XF86_GlxVisualsTypical,
XF86_GlxVisualsAll,
} XF86_GlxVisuals;
/* /*
* xf86InfoRec contains global parameters which the video drivers never * xf86InfoRec contains global parameters which the video drivers never
* need to access. Global parameters which the video drivers do need * need to access. Global parameters which the video drivers do need
@ -120,6 +126,9 @@ typedef struct {
MessageType randRFrom; MessageType randRFrom;
Bool aiglx; Bool aiglx;
MessageType aiglxFrom; MessageType aiglxFrom;
XF86_GlxVisuals glxVisuals;
MessageType glxVisualsFrom;
Bool useDefaultFontPath; Bool useDefaultFontPath;
MessageType useDefaultFontPathFrom; MessageType useDefaultFontPathFrom;
Bool ignoreABI; Bool ignoreABI;

View File

@ -41,18 +41,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "colormap.h" #include "colormap.h"
#include "micmap.h" #include "micmap.h"
#include "globals.h" #include "globals.h"
#include "glxserver.h"
typedef struct __GLXscreen __GLXscreen;
typedef struct __GLXprovider __GLXprovider;
struct __GLXprovider {
__GLXscreen *(*screenProbe)(ScreenPtr pScreen);
const char *name;
__GLXprovider *next;
};
extern void GlxPushProvider(__GLXprovider *provider);
extern void GlxExtensionInit(void);
extern void GlxWrapInitVisuals(miInitVisualsProcPtr *);
static MODULESETUPPROTO(glxSetup); static MODULESETUPPROTO(glxSetup);
@ -114,7 +103,6 @@ static __GLXprovider __glXMesaProxyProvider = {
NULL NULL
}; };
static pointer static pointer
glxSetup(pointer module, pointer opts, int *errmaj, int *errmin) glxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
{ {
@ -139,12 +127,22 @@ glxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
GlxPushProvider(provider); GlxPushProvider(provider);
} }
LoadExtension(&GLXExt, FALSE); switch (xf86Info.glxVisuals) {
/* Wrap the init visuals routine in micmap.c */ case XF86_GlxVisualsMinimal:
GlxWrapInitVisuals(&miInitVisualsProc); GlxSetVisualConfig(GLX_MINIMAL_VISUALS);
/* Make sure this gets wrapped each time InitVisualWrap is called */ xf86Msg(xf86Info.aiglxFrom, "Exporting only minimal set of GLX visuals\n");
miHookInitVisuals(NULL, GlxWrapInitVisuals); break;
case XF86_GlxVisualsTypical:
GlxSetVisualConfig(GLX_TYPICAL_VISUALS);
xf86Msg(xf86Info.aiglxFrom, "Exporting typical set of GLX visuals\n");
break;
case XF86_GlxVisualsAll:
GlxSetVisualConfig(GLX_ALL_VISUALS);
xf86Msg(xf86Info.aiglxFrom, "Exporting all GLX visuals\n");
break;
}
LoadExtension(&GLXExt, FALSE);
bail:
return module; return module;
} }

View File

@ -700,6 +700,17 @@ the builtin handler will be used.
.BI "Option \*qAIGLX\*q \*q" boolean \*q .BI "Option \*qAIGLX\*q \*q" boolean \*q
enable or disable AIGLX. AIGLX is enabled by default. enable or disable AIGLX. AIGLX is enabled by default.
.TP 7 .TP 7
.BI "Option \*qGlxVisuals\*q \*q" string \*q
This option controls how many GLX visuals the GLX modules sets up.
The default value is
.BR "typical" ,
which will setup up a typical subset of
the GLXFBConfigs provided by the driver as GLX visuals. Other options are
.BR "minimal" ,
which will set up the minimal set allowed by the GLX specification and
.BR "all"
which will setup GLX visuals for all GLXFBConfigs.
.TP 7
.BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q .BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q
Include the default font path even if other paths are specified in Include the default font path even if other paths are specified in
xorg.conf. If enabled, other font paths are included as well. Enabled by xorg.conf. If enabled, other font paths are included as well. Enabled by

View File

@ -67,7 +67,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "dristruct.h" #include "dristruct.h"
#include "xf86.h" #include "xf86.h"
#include "xf86drm.h" #include "xf86drm.h"
#include "glxserver.h"
#include "mi.h" #include "mi.h"
#include "mipointer.h" #include "mipointer.h"
#include "xf86_OSproc.h" #include "xf86_OSproc.h"
@ -953,24 +952,8 @@ static Bool
DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv) DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv)
{ {
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
__GLXscreen *pGLXScreen = glxGetScreen(pScreen);
__GLcontextModes *modes = pGLXScreen->modes;
void **pVisualConfigPriv = pGLXScreen->pVisualPriv;
DRIContextPrivPtr pDRIContextPriv; DRIContextPrivPtr pDRIContextPriv;
void *contextStore; void *contextStore;
VisualPtr visual;
int visNum;
visual = pScreen->visuals;
/* Find the X visual that corresponds the the first GLX visual */
for (visNum = 0;
visNum < pScreen->numVisuals;
visNum++, visual++) {
if (modes->visualID == visual->vid)
break;
}
if (visNum == pScreen->numVisuals) return FALSE;
if (!(pDRIContextPriv = if (!(pDRIContextPriv =
DRICreateContextPriv(pScreen, DRICreateContextPriv(pScreen,
@ -980,9 +963,9 @@ DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv)
contextStore = DRIGetContextStore(pDRIContextPriv); contextStore = DRIGetContextStore(pDRIContextPriv);
if (pDRIPriv->pDriverInfo->CreateContext && needCtxPriv) { if (pDRIPriv->pDriverInfo->CreateContext && needCtxPriv) {
if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, visual, if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, NULL,
pDRIPriv->pSAREA->dummy_context, pDRIPriv->pSAREA->dummy_context,
*pVisualConfigPriv, NULL,
(DRIContextType)(long)contextStore)) { (DRIContextType)(long)contextStore)) {
DRIDestroyContextPriv(pDRIContextPriv); DRIDestroyContextPriv(pDRIContextPriv);
return FALSE; return FALSE;
@ -1017,9 +1000,6 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
XID context, drm_context_t * pHWContext) XID context, drm_context_t * pHWContext)
{ {
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
__GLXscreen *pGLXScreen = glxGetScreen(pScreen);
__GLcontextModes *modes = pGLXScreen->modes;
void **pVisualConfigPriv = pGLXScreen->pVisualPriv;
DRIContextPrivPtr pDRIContextPriv; DRIContextPrivPtr pDRIContextPriv;
void *contextStore; void *contextStore;
@ -1031,26 +1011,14 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
} }
} }
/* Find the GLX visual associated with the one requested */
for (modes = pGLXScreen->modes; modes != NULL; modes = modes->next) {
if (modes->visualID == visual->vid)
break;
pVisualConfigPriv++;
}
if (modes == NULL) {
/* No matching GLX visual found */
return FALSE;
}
if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, pHWContext, 0))) { if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, pHWContext, 0))) {
return FALSE; return FALSE;
} }
contextStore = DRIGetContextStore(pDRIContextPriv); contextStore = DRIGetContextStore(pDRIContextPriv);
if (pDRIPriv->pDriverInfo->CreateContext) { if (pDRIPriv->pDriverInfo->CreateContext) {
if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, visual, if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, NULL,
*pHWContext, *pVisualConfigPriv, *pHWContext, NULL,
(DRIContextType)(long)contextStore))) { (DRIContextType)(long)contextStore))) {
DRIDestroyContextPriv(pDRIContextPriv); DRIDestroyContextPriv(pDRIContextPriv);
return FALSE; return FALSE;

View File

@ -373,19 +373,9 @@ ProcXF86DRICreateContext(
rep.sequenceNumber = client->sequence; rep.sequenceNumber = client->sequence;
pScreen = screenInfo.screens[stuff->screen]; pScreen = screenInfo.screens[stuff->screen];
visual = pScreen->visuals;
/* Find the requested X visual */
for (i = 0; i < pScreen->numVisuals; i++, visual++)
if (visual->vid == stuff->visual)
break;
if (i == pScreen->numVisuals) {
/* No visual found */
return BadValue;
}
if (!DRICreateContext( pScreen, if (!DRICreateContext( pScreen,
visual, NULL,
stuff->context, stuff->context,
(drm_context_t *)&rep.hHWContext)) { (drm_context_t *)&rep.hHWContext)) {
return BadValue; return BadValue;

View File

@ -205,9 +205,6 @@ _X_HIDDEN void *miLookupTab[] = {
SYMVAR(miPointerScreenKey) SYMVAR(miPointerScreenKey)
SYMVAR(miInstalledMaps) SYMVAR(miInstalledMaps)
SYMVAR(miInitVisualsProc) SYMVAR(miInitVisualsProc)
#ifdef RENDER
SYMFUNC(miGlyphExtents)
#endif
#ifdef DAMAGE #ifdef DAMAGE
SYMFUNC(DamageDamageRegion) SYMFUNC(DamageDamageRegion)
#endif #endif

View File

@ -1417,9 +1417,8 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
output->probed_modes = mode; output->probed_modes = mode;
} }
mode->type |= (M_T_PREFERRED|M_T_USERPREF); mode->type |= (M_T_PREFERRED|M_T_USERPREF);
break;
} }
else
mode->type &= ~M_T_PREFERRED;
} }
} }

View File

@ -64,6 +64,8 @@ typedef enum {
* maximum size and use that. * maximum size and use that.
*/ */
DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5, DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5,
/* Monitor forgot to set the first detailed is preferred bit. */
DDC_QUIRK_FIRST_DETAILED_PREFERRED = 1 << 6,
} ddc_quirk_t; } ddc_quirk_t;
static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
@ -147,6 +149,16 @@ static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC)
return FALSE; return FALSE;
} }
static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC)
{
/* Philips 107p5 CRT. Reported on xorg@ with pastebin. */
if (memcmp (DDC->vendor.name, "PHL", 4) == 0 &&
DDC->vendor.prod_id == 57364)
return TRUE;
return FALSE;
}
typedef struct { typedef struct {
Bool (*detect) (int scrnIndex, xf86MonPtr DDC); Bool (*detect) (int scrnIndex, xf86MonPtr DDC);
ddc_quirk_t quirk; ddc_quirk_t quirk;
@ -178,6 +190,10 @@ static const ddc_quirk_map_t ddc_quirks[] = {
quirk_detailed_use_maximum_size, DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE, quirk_detailed_use_maximum_size, DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE,
"Detailed timings give sizes in cm." "Detailed timings give sizes in cm."
}, },
{
quirk_first_detailed_preferred, DDC_QUIRK_FIRST_DETAILED_PREFERRED,
"First detailed timing was not marked as preferred."
},
{ {
NULL, DDC_QUIRK_NONE, NULL, DDC_QUIRK_NONE,
"No known quirks" "No known quirks"
@ -257,7 +273,7 @@ DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing,
*/ */
static DisplayModePtr static DisplayModePtr
DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
int preferred, ddc_quirk_t quirks) Bool preferred, ddc_quirk_t quirks)
{ {
DisplayModePtr Mode; DisplayModePtr Mode;
@ -470,9 +486,10 @@ xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes,
_X_EXPORT DisplayModePtr _X_EXPORT DisplayModePtr
xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
{ {
int preferred, i; int i;
DisplayModePtr Modes = NULL, Mode; DisplayModePtr Modes = NULL, Mode;
ddc_quirk_t quirks; ddc_quirk_t quirks;
Bool preferred;
xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n", xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
DDC->vendor.name, DDC->vendor.prod_id); DDC->vendor.name, DDC->vendor.prod_id);
@ -480,8 +497,10 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE); quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE);
preferred = PREFERRED_TIMING_MODE(DDC->features.msc); preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
if (quirks & DDC_QUIRK_PREFER_LARGE_60) if (quirks & DDC_QUIRK_FIRST_DETAILED_PREFERRED)
preferred = 0; preferred = TRUE;
if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75))
preferred = FALSE;
for (i = 0; i < DET_TIMINGS; i++) { for (i = 0; i < DET_TIMINGS; i++) {
struct detailed_monitor_section *det_mon = &DDC->det_mon[i]; struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
@ -492,7 +511,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
&det_mon->section.d_timings, &det_mon->section.d_timings,
preferred, preferred,
quirks); quirks);
preferred = 0; preferred = FALSE;
Modes = xf86ModesAdd(Modes, Mode); Modes = xf86ModesAdd(Modes, Mode);
break; break;
case DS_STD_TIMINGS: case DS_STD_TIMINGS:

View File

@ -426,8 +426,18 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
xf86OutputPtr output = config->output[config->compat_output]; xf86OutputPtr output = config->output[config->compat_output];
xf86CrtcPtr crtc = output->crtc; xf86CrtcPtr crtc = output->crtc;
if (crtc && crtc->mode.HDisplay && if (output->conf_monitor &&
output->mm_width && output->mm_height) (output->conf_monitor->mon_width > 0 &&
output->conf_monitor->mon_height > 0))
{
/*
* Prefer user configured DisplaySize
*/
mmWidth = output->conf_monitor->mon_width;
mmHeight = output->conf_monitor->mon_height;
}
else if (crtc && crtc->mode.HDisplay &&
output->mm_width && output->mm_height)
{ {
/* /*
* If the output has a mode and a declared size, use that * If the output has a mode and a declared size, use that

View File

@ -23,11 +23,11 @@
#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83
#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84
#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82 #define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85
#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83 #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84 #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85 #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88
#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86 #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89
#define ACPI_VIDEO_HEAD_INVALID (~0u - 1) #define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
#define ACPI_VIDEO_HEAD_END (~0u) #define ACPI_VIDEO_HEAD_END (~0u)
@ -69,9 +69,11 @@ lnxACPIGetEventFromOs(int fd, pmEvent *events, int num)
TimerSet(NULL, 0, ACPI_REOPEN_DELAY, lnxACPIReopen, NULL); TimerSet(NULL, 0, ACPI_REOPEN_DELAY, lnxACPIReopen, NULL);
return 0; return 0;
} }
/* FIXME: this only processes the first read ACPI event & might break
* with interrupted reads. */
/* Check that we have a video event */ /* Check that we have a video event */
if (strstr(ev, "video") == ev) { if (!strncmp(ev, "video", 5)) {
char *video = NULL; char *video = NULL;
char *GFX = NULL; char *GFX = NULL;
char *notify = NULL; char *notify = NULL;
@ -97,26 +99,19 @@ lnxACPIGetEventFromOs(int fd, pmEvent *events, int num)
ErrorF("data: 0x%lx\n",data_l); ErrorF("data: 0x%lx\n",data_l);
#endif #endif
/* We currently don't differentiate between any event */ /* Differentiate between events */
switch (notify_l) { switch (notify_l) {
case ACPI_VIDEO_NOTIFY_SWITCH: case ACPI_VIDEO_NOTIFY_SWITCH:
break;
case ACPI_VIDEO_NOTIFY_PROBE:
break;
case ACPI_VIDEO_NOTIFY_CYCLE: case ACPI_VIDEO_NOTIFY_CYCLE:
break;
case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT:
break;
case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: case ACPI_VIDEO_NOTIFY_PREV_OUTPUT:
break; events[0] = XF86_APM_CAPABILITY_CHANGED;
return 1;
case ACPI_VIDEO_NOTIFY_PROBE:
return 0;
default: default:
break; return 0;
} }
/* Deal with all ACPI events as a capability change */
events[0] = XF86_APM_CAPABILITY_CHANGED;
return 1;
} }
return 0; return 0;

View File

@ -45,10 +45,6 @@ is" without express or implied warranty.
Window xnestDefaultWindows[MAXSCREENS]; Window xnestDefaultWindows[MAXSCREENS];
Window xnestScreenSaverWindows[MAXSCREENS]; Window xnestScreenSaverWindows[MAXSCREENS];
#ifdef GLXEXT
extern void GlxWrapInitVisuals(miInitVisualsProcPtr *);
#endif
ScreenPtr ScreenPtr
xnestScreen(Window window) xnestScreen(Window window)
{ {
@ -220,17 +216,6 @@ xnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[])
defaultVisual = visuals[xnestDefaultVisualIndex].vid; defaultVisual = visuals[xnestDefaultVisualIndex].vid;
rootDepth = visuals[xnestDefaultVisualIndex].nplanes; rootDepth = visuals[xnestDefaultVisualIndex].nplanes;
#ifdef GLXEXT
{
miInitVisualsProcPtr proc = NULL;
GlxWrapInitVisuals(&proc);
/* GlxInitVisuals ignores the last three arguments. */
proc(&visuals, &depths, &numVisuals, &numDepths,
&rootDepth, &defaultVisual, 0, 0, 0);
}
#endif
if (xnestParentWindow != 0) { if (xnestParentWindow != 0) {
XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes); XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes);
xnestWidth = gattributes.width; xnestWidth = gattributes.width;

View File

@ -517,7 +517,7 @@ __attribute((noreturn))
#ifdef DEBUG #ifdef DEBUG
#define DebugF ErrorF #define DebugF ErrorF
#else #else
#define DebugF(x, ...) /* */ #define DebugF(...) /* */
#endif #endif
extern void VErrorF(const char *f, va_list args); extern void VErrorF(const char *f, va_list args);

View File

@ -112,4 +112,7 @@
/* Have execinfo.h */ /* Have execinfo.h */
#undef HAVE_EXECINFO_H #undef HAVE_EXECINFO_H
/* Path to text files containing PCI IDs */
#undef PCI_TXT_IDS_PATH
#endif /* _XORG_CONFIG_H_ */ #endif /* _XORG_CONFIG_H_ */

View File

@ -352,7 +352,6 @@ extern void DarwinGlxWrapInitVisuals(miInitVisualsProcPtr *);
extern __GLXprovider __glXMesaProvider; extern __GLXprovider __glXMesaProvider;
extern void GlxPushProvider(__GLXprovider *impl); extern void GlxPushProvider(__GLXprovider *impl);
extern void GlxExtensionInit(INITARGS); extern void GlxExtensionInit(INITARGS);
extern void GlxWrapInitVisuals(miInitVisualsProcPtr *);
#endif // INXDARWINAPP #endif // INXDARWINAPP
#endif // GLXEXT #endif // GLXEXT
#ifdef XF86DRI #ifdef XF86DRI
@ -678,9 +677,7 @@ InitVisualWrap()
{ {
miResetInitVisuals(); miResetInitVisuals();
#ifdef GLXEXT #ifdef GLXEXT
#ifndef __DARWIN__ #ifdef __DARWIN__
GlxWrapInitVisuals(&miInitVisualsProc);
#else
DarwinGlxWrapInitVisuals(&miInitVisualsProc); DarwinGlxWrapInitVisuals(&miInitVisualsProc);
#endif #endif
#endif #endif

View File

@ -99,7 +99,6 @@ typedef struct {
ValidatePictureProcPtr ValidatePicture; ValidatePictureProcPtr ValidatePicture;
CompositeProcPtr Composite; CompositeProcPtr Composite;
GlyphsProcPtr Glyphs;
CompositeRectsProcPtr CompositeRects; CompositeRectsProcPtr CompositeRects;
TrapezoidsProcPtr Trapezoids; TrapezoidsProcPtr Trapezoids;

View File

@ -279,34 +279,6 @@ cwComposite (CARD8 op,
cwPsWrap(Composite, cwComposite); cwPsWrap(Composite, cwComposite);
} }
static void
cwGlyphs (CARD8 op,
PicturePtr pSrcPicture,
PicturePtr pDstPicture,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nlists,
GlyphListPtr lists,
GlyphPtr *glyphs)
{
ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
cwPsDecl(pScreen);
cwSrcPictureDecl;
cwDstPictureDecl;
cwPsUnwrap(Glyphs);
if (nlists)
{
lists->xOff += dst_picture_x_off;
lists->yOff += dst_picture_y_off;
}
(*ps->Glyphs) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
xSrc + src_picture_x_off, ySrc + src_picture_y_off,
nlists, lists, glyphs);
cwPsWrap(Glyphs, cwGlyphs);
}
static void static void
cwCompositeRects (CARD8 op, cwCompositeRects (CARD8 op,
PicturePtr pDstPicture, PicturePtr pDstPicture,
@ -470,7 +442,6 @@ cwInitializeRender (ScreenPtr pScreen)
cwPsWrap(ChangePicture, cwChangePicture); cwPsWrap(ChangePicture, cwChangePicture);
cwPsWrap(ValidatePicture, cwValidatePicture); cwPsWrap(ValidatePicture, cwValidatePicture);
cwPsWrap(Composite, cwComposite); cwPsWrap(Composite, cwComposite);
cwPsWrap(Glyphs, cwGlyphs);
cwPsWrap(CompositeRects, cwCompositeRects); cwPsWrap(CompositeRects, cwCompositeRects);
cwPsWrap(Trapezoids, cwTrapezoids); cwPsWrap(Trapezoids, cwTrapezoids);
cwPsWrap(Triangles, cwTriangles); cwPsWrap(Triangles, cwTriangles);
@ -491,7 +462,6 @@ cwFiniRender (ScreenPtr pScreen)
cwPsUnwrap(ChangePicture); cwPsUnwrap(ChangePicture);
cwPsUnwrap(ValidatePicture); cwPsUnwrap(ValidatePicture);
cwPsUnwrap(Composite); cwPsUnwrap(Composite);
cwPsUnwrap(Glyphs);
cwPsUnwrap(CompositeRects); cwPsUnwrap(CompositeRects);
cwPsUnwrap(Trapezoids); cwPsUnwrap(Trapezoids);
cwPsUnwrap(Triangles); cwPsUnwrap(Triangles);

View File

@ -6,7 +6,6 @@ librender_la_SOURCES = \
animcur.c \ animcur.c \
filter.c \ filter.c \
glyph.c \ glyph.c \
miglyph.c \
miindex.c \ miindex.c \
mipict.c \ mipict.c \
mirect.c \ mirect.c \

View File

@ -26,6 +26,9 @@
#include <dix-config.h> #include <dix-config.h>
#endif #endif
#include <stddef.h>
#include <openssl/sha.h>
#include "misc.h" #include "misc.h"
#include "scrnintstr.h" #include "scrnintstr.h"
#include "os.h" #include "os.h"
@ -41,6 +44,7 @@
#include "servermd.h" #include "servermd.h"
#include "picturestr.h" #include "picturestr.h"
#include "glyphstr.h" #include "glyphstr.h"
#include "mipict.h"
/* /*
* From Knuth -- a good choice for hash/rehash values is p, p-2 where * From Knuth -- a good choice for hash/rehash values is p, p-2 where
@ -93,6 +97,7 @@ FreeGlyphPrivates (GlyphPtr glyph)
} }
dixFreePrivates(glyph->devPrivates); dixFreePrivates(glyph->devPrivates);
glyph->devPrivates = NULL;
} }
void void
@ -114,7 +119,6 @@ GlyphUninit (ScreenPtr pScreen)
{ {
(*ps->UnrealizeGlyph) (pScreen, glyph); (*ps->UnrealizeGlyph) (pScreen, glyph);
FreeGlyphPrivates(glyph); FreeGlyphPrivates(glyph);
glyph->devPrivates = NULL;
} }
} }
} }
@ -141,7 +145,10 @@ FindGlyphHashSet (CARD32 filled)
} }
GlyphRefPtr GlyphRefPtr
FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) FindGlyphRef (GlyphHashPtr hash,
CARD32 signature,
Bool match,
unsigned char sha1[20])
{ {
CARD32 elt, step, s; CARD32 elt, step, s;
GlyphPtr glyph; GlyphPtr glyph;
@ -172,7 +179,7 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
} }
else if (s == signature && else if (s == signature &&
(!match || (!match ||
memcmp (&compare->info, &glyph->info, compare->size) == 0)) memcmp (glyph->sha1, sha1, 20) == 0))
{ {
break; break;
} }
@ -189,17 +196,47 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
return gr; return gr;
} }
CARD32 int
HashGlyph (GlyphPtr glyph) HashGlyph (xGlyphInfo *gi,
CARD8 *bits,
unsigned long size,
unsigned char sha1[20])
{ {
CARD32 *bits = (CARD32 *) &(glyph->info); SHA_CTX ctx;
CARD32 hash; int success;
int n = glyph->size / sizeof (CARD32);
hash = 0; success = SHA1_Init (&ctx);
while (n--) if (! success)
hash ^= *bits++; return BadAlloc;
return hash;
success = SHA1_Update (&ctx, gi, sizeof (xGlyphInfo));
if (! success)
return BadAlloc;
success = SHA1_Update (&ctx, bits, size);
if (! success)
return BadAlloc;
success = SHA1_Final (sha1, &ctx);
if (! success)
return BadAlloc;
return Success;
}
GlyphPtr
FindGlyphByHash (unsigned char sha1[20], int format)
{
GlyphRefPtr gr;
CARD32 signature = *(CARD32 *) sha1;
gr = FindGlyphRef (&globalGlyphs[format],
signature, TRUE, sha1);
if (gr->glyph && gr->glyph != DeletedGlyph)
return gr->glyph;
else
return NULL;
} }
#ifdef CHECK_DUPLICATES #ifdef CHECK_DUPLICATES
@ -240,6 +277,7 @@ FreeGlyph (GlyphPtr glyph, int format)
GlyphRefPtr gr; GlyphRefPtr gr;
int i; int i;
int first; int first;
CARD32 signature;
first = -1; first = -1;
for (i = 0; i < globalGlyphs[format].hashSet->size; i++) for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
@ -250,8 +288,9 @@ FreeGlyph (GlyphPtr glyph, int format)
first = i; first = i;
} }
gr = FindGlyphRef (&globalGlyphs[format], signature = *(CARD32 *) glyph->sha1;
HashGlyph (glyph), TRUE, glyph); gr = FindGlyphRef (&globalGlyphs[format], signature,
TRUE, glyph->sha1);
if (gr - globalGlyphs[format].table != first) if (gr - globalGlyphs[format].table != first)
DuplicateRef (glyph, "Found wrong one"); DuplicateRef (glyph, "Found wrong one");
if (gr->glyph && gr->glyph != DeletedGlyph) if (gr->glyph && gr->glyph != DeletedGlyph)
@ -263,9 +302,13 @@ FreeGlyph (GlyphPtr glyph, int format)
for (i = 0; i < screenInfo.numScreens; i++) for (i = 0; i < screenInfo.numScreens; i++)
{ {
ps = GetPictureScreenIfSet (screenInfo.screens[i]); ScreenPtr pScreen = screenInfo.screens[i];
FreePicture ((pointer) GlyphPicture (glyph)[i], 0);
ps = GetPictureScreenIfSet (pScreen);
if (ps) if (ps)
(*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); (*ps->UnrealizeGlyph) (pScreen, glyph);
} }
FreeGlyphPrivates(glyph); FreeGlyphPrivates(glyph);
@ -277,13 +320,14 @@ void
AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
{ {
GlyphRefPtr gr; GlyphRefPtr gr;
CARD32 hash; CARD32 signature;
CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global"); CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
/* Locate existing matching glyph */ /* Locate existing matching glyph */
hash = HashGlyph (glyph); signature = *(CARD32 *) glyph->sha1;
gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph); gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], signature,
if (gr->glyph && gr->glyph != DeletedGlyph) TRUE, glyph->sha1);
if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph)
{ {
PictureScreenPtr ps; PictureScreenPtr ps;
int i; int i;
@ -298,10 +342,10 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
xfree (glyph); xfree (glyph);
glyph = gr->glyph; glyph = gr->glyph;
} }
else else if (gr->glyph != glyph)
{ {
gr->glyph = glyph; gr->glyph = glyph;
gr->signature = hash; gr->signature = signature;
globalGlyphs[glyphSet->fdepth].tableEntries++; globalGlyphs[glyphSet->fdepth].tableEntries++;
} }
@ -354,7 +398,7 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
GlyphPtr glyph; GlyphPtr glyph;
int i; int i;
size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]); size = screenInfo.numScreens * sizeof (PicturePtr);
glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec)); glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
if (!glyph) if (!glyph)
return 0; return 0;
@ -366,25 +410,27 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
for (i = 0; i < screenInfo.numScreens; i++) for (i = 0; i < screenInfo.numScreens; i++)
{ {
ps = GetPictureScreenIfSet (screenInfo.screens[i]); ps = GetPictureScreenIfSet (screenInfo.screens[i]);
if (ps) if (ps)
{ {
if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph))
{ goto bail;
while (i--)
{
ps = GetPictureScreenIfSet (screenInfo.screens[i]);
if (ps)
(*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
}
FreeGlyphPrivates(glyph);
xfree (glyph);
return 0;
}
} }
} }
return glyph; return glyph;
bail:
while (i--)
{
ps = GetPictureScreenIfSet (screenInfo.screens[i]);
if (ps)
(*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
}
FreeGlyphPrivates(glyph);
xfree (glyph);
return 0;
} }
Bool Bool
@ -428,7 +474,7 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
if (glyph && glyph != DeletedGlyph) if (glyph && glyph != DeletedGlyph)
{ {
s = hash->table[i].signature; s = hash->table[i].signature;
gr = FindGlyphRef (&newHash, s, global, glyph); gr = FindGlyphRef (&newHash, s, global, glyph->sha1);
gr->signature = s; gr->signature = s;
gr->glyph = glyph; gr->glyph = glyph;
++newHash.tableEntries; ++newHash.tableEntries;
@ -510,3 +556,215 @@ FreeGlyphSet (pointer value,
} }
return Success; return Success;
} }
static void
GlyphExtents (int nlist,
GlyphListPtr list,
GlyphPtr *glyphs,
BoxPtr extents)
{
int x1, x2, y1, y2;
int n;
GlyphPtr glyph;
int x, y;
x = 0;
y = 0;
extents->x1 = MAXSHORT;
extents->x2 = MINSHORT;
extents->y1 = MAXSHORT;
extents->y2 = MINSHORT;
while (nlist--)
{
x += list->xOff;
y += list->yOff;
n = list->len;
list++;
while (n--)
{
glyph = *glyphs++;
x1 = x - glyph->info.x;
if (x1 < MINSHORT)
x1 = MINSHORT;
y1 = y - glyph->info.y;
if (y1 < MINSHORT)
y1 = MINSHORT;
x2 = x1 + glyph->info.width;
if (x2 > MAXSHORT)
x2 = MAXSHORT;
y2 = y1 + glyph->info.height;
if (y2 > MAXSHORT)
y2 = MAXSHORT;
if (x1 < extents->x1)
extents->x1 = x1;
if (x2 > extents->x2)
extents->x2 = x2;
if (y1 < extents->y1)
extents->y1 = y1;
if (y2 > extents->y2)
extents->y2 = y2;
x += glyph->info.xOff;
y += glyph->info.yOff;
}
}
}
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
/* Stub ABI compatibility for mi*Glyph, should go away */
_X_EXPORT void
miGlyphs (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nlist,
GlyphListPtr list,
GlyphPtr *glyphs)
{
CompositeGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list,
glyphs);
}
Bool
miRealizeGlyph (ScreenPtr pScreen,
GlyphPtr glyph)
{
return TRUE;
}
void
miUnrealizeGlyph (ScreenPtr pScreen,
GlyphPtr glyph)
{
}
_X_EXPORT void
CompositeGlyphs (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nlist,
GlyphListPtr list,
GlyphPtr *glyphs)
{
PicturePtr pPicture;
PixmapPtr pMaskPixmap = 0;
PicturePtr pMask;
ScreenPtr pScreen = pDst->pDrawable->pScreen;
int width = 0, height = 0;
int x, y;
int xDst = list->xOff, yDst = list->yOff;
int n;
GlyphPtr glyph;
int error;
BoxRec extents = {0, 0, 0, 0};
CARD32 component_alpha;
ValidatePicture (pSrc);
ValidatePicture (pDst);
if (maskFormat)
{
GCPtr pGC;
xRectangle rect;
GlyphExtents (nlist, list, glyphs, &extents);
if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
return;
width = extents.x2 - extents.x1;
height = extents.y2 - extents.y1;
pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
maskFormat->depth);
if (!pMaskPixmap)
return;
component_alpha = NeedsComponent(maskFormat->format);
pMask = CreatePicture (0, &pMaskPixmap->drawable,
maskFormat, CPComponentAlpha, &component_alpha,
serverClient, &error);
if (!pMask)
{
(*pScreen->DestroyPixmap) (pMaskPixmap);
return;
}
pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
ValidateGC (&pMaskPixmap->drawable, pGC);
rect.x = 0;
rect.y = 0;
rect.width = width;
rect.height = height;
(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
FreeScratchGC (pGC);
x = -extents.x1;
y = -extents.y1;
}
else
{
pMask = pDst;
x = 0;
y = 0;
}
while (nlist--)
{
x += list->xOff;
y += list->yOff;
n = list->len;
while (n--)
{
glyph = *glyphs++;
pPicture = GlyphPicture (glyph)[pScreen->myNum];
if (maskFormat)
{
CompositePicture (PictOpAdd,
pPicture,
None,
pMask,
0, 0,
0, 0,
x - glyph->info.x,
y - glyph->info.y,
glyph->info.width,
glyph->info.height);
}
else
{
CompositePicture (op,
pSrc,
pPicture,
pDst,
xSrc + (x - glyph->info.x) - xDst,
ySrc + (y - glyph->info.y) - yDst,
0, 0,
x - glyph->info.x,
y - glyph->info.y,
glyph->info.width,
glyph->info.height);
}
x += glyph->info.xOff;
y += glyph->info.yOff;
}
list++;
}
if (maskFormat)
{
x = extents.x1;
y = extents.y1;
CompositePicture (op,
pSrc,
pMask,
pDst,
xSrc + x - xDst,
ySrc + y - yDst,
0, 0,
x, y,
width, height);
FreePicture ((pointer) pMask, (XID) 0);
(*pScreen->DestroyPixmap) (pMaskPixmap);
}
}

View File

@ -40,13 +40,16 @@
#define GlyphFormatNum 5 #define GlyphFormatNum 5
typedef struct _Glyph { typedef struct _Glyph {
CARD32 refcnt; CARD32 refcnt;
PrivateRec *devPrivates; PrivateRec *devPrivates;
CARD32 size; /* info + bitmap */ unsigned char sha1[20];
xGlyphInfo info; CARD32 size; /* info + bitmap */
/* bits follow */ xGlyphInfo info;
/* per-screen pixmaps follow */
} GlyphRec, *GlyphPtr; } GlyphRec, *GlyphPtr;
#define GlyphPicture(glyph) ((PicturePtr *) ((glyph) + 1))
typedef struct _GlyphRef { typedef struct _GlyphRef {
CARD32 signature; CARD32 signature;
GlyphPtr glyph; GlyphPtr glyph;
@ -98,10 +101,19 @@ GlyphHashSetPtr
FindGlyphHashSet (CARD32 filled); FindGlyphHashSet (CARD32 filled);
GlyphRefPtr GlyphRefPtr
FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare); FindGlyphRef (GlyphHashPtr hash,
CARD32 signature,
Bool match,
unsigned char sha1[20]);
CARD32 GlyphPtr
HashGlyph (GlyphPtr glyph); FindGlyphByHash (unsigned char sha1[20], int format);
int
HashGlyph (xGlyphInfo *gi,
CARD8 *bits,
unsigned long size,
unsigned char sha1[20]);
void void
FreeGlyph (GlyphPtr glyph, int format); FreeGlyph (GlyphPtr glyph, int format);

View File

@ -1,255 +0,0 @@
/*
*
* Copyright © 2000 SuSE, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of SuSE not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. SuSE makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Keith Packard, SuSE, Inc.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "scrnintstr.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "mi.h"
#include "picturestr.h"
#include "mipict.h"
Bool
miRealizeGlyph (ScreenPtr pScreen,
GlyphPtr glyph)
{
return TRUE;
}
void
miUnrealizeGlyph (ScreenPtr pScreen,
GlyphPtr glyph)
{
}
_X_EXPORT void
miGlyphExtents (int nlist,
GlyphListPtr list,
GlyphPtr *glyphs,
BoxPtr extents)
{
int x1, x2, y1, y2;
int n;
GlyphPtr glyph;
int x, y;
x = 0;
y = 0;
extents->x1 = MAXSHORT;
extents->x2 = MINSHORT;
extents->y1 = MAXSHORT;
extents->y2 = MINSHORT;
while (nlist--)
{
x += list->xOff;
y += list->yOff;
n = list->len;
list++;
while (n--)
{
glyph = *glyphs++;
x1 = x - glyph->info.x;
if (x1 < MINSHORT)
x1 = MINSHORT;
y1 = y - glyph->info.y;
if (y1 < MINSHORT)
y1 = MINSHORT;
x2 = x1 + glyph->info.width;
if (x2 > MAXSHORT)
x2 = MAXSHORT;
y2 = y1 + glyph->info.height;
if (y2 > MAXSHORT)
y2 = MAXSHORT;
if (x1 < extents->x1)
extents->x1 = x1;
if (x2 > extents->x2)
extents->x2 = x2;
if (y1 < extents->y1)
extents->y1 = y1;
if (y2 > extents->y2)
extents->y2 = y2;
x += glyph->info.xOff;
y += glyph->info.yOff;
}
}
}
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
_X_EXPORT void
miGlyphs (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nlist,
GlyphListPtr list,
GlyphPtr *glyphs)
{
PixmapPtr pPixmap = 0;
PicturePtr pPicture;
PixmapPtr pMaskPixmap = 0;
PicturePtr pMask;
ScreenPtr pScreen = pDst->pDrawable->pScreen;
int width = 0, height = 0;
int x, y;
int xDst = list->xOff, yDst = list->yOff;
int n;
GlyphPtr glyph;
int error;
BoxRec extents;
CARD32 component_alpha;
if (maskFormat)
{
GCPtr pGC;
xRectangle rect;
miGlyphExtents (nlist, list, glyphs, &extents);
if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
return;
width = extents.x2 - extents.x1;
height = extents.y2 - extents.y1;
pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
if (!pMaskPixmap)
return;
component_alpha = NeedsComponent(maskFormat->format);
pMask = CreatePicture (0, &pMaskPixmap->drawable,
maskFormat, CPComponentAlpha, &component_alpha,
serverClient, &error);
if (!pMask)
{
(*pScreen->DestroyPixmap) (pMaskPixmap);
return;
}
pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
ValidateGC (&pMaskPixmap->drawable, pGC);
rect.x = 0;
rect.y = 0;
rect.width = width;
rect.height = height;
(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
FreeScratchGC (pGC);
x = -extents.x1;
y = -extents.y1;
}
else
{
pMask = pDst;
x = 0;
y = 0;
}
pPicture = 0;
while (nlist--)
{
x += list->xOff;
y += list->yOff;
n = list->len;
while (n--)
{
glyph = *glyphs++;
if (!pPicture)
{
pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height,
list->format->depth,
list->format->depth,
0, (pointer) (glyph + 1));
if (!pPixmap)
return;
component_alpha = NeedsComponent(list->format->format);
pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
CPComponentAlpha, &component_alpha,
serverClient, &error);
if (!pPicture)
{
FreeScratchPixmapHeader (pPixmap);
return;
}
}
(*pScreen->ModifyPixmapHeader) (pPixmap,
glyph->info.width, glyph->info.height,
0, 0, -1, (pointer) (glyph + 1));
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
if (maskFormat)
{
CompositePicture (PictOpAdd,
pPicture,
None,
pMask,
0, 0,
0, 0,
x - glyph->info.x,
y - glyph->info.y,
glyph->info.width,
glyph->info.height);
}
else
{
CompositePicture (op,
pSrc,
pPicture,
pDst,
xSrc + (x - glyph->info.x) - xDst,
ySrc + (y - glyph->info.y) - yDst,
0, 0,
x - glyph->info.x,
y - glyph->info.y,
glyph->info.width,
glyph->info.height);
}
x += glyph->info.xOff;
y += glyph->info.yOff;
}
list++;
if (pPicture)
{
FreeScratchPixmapHeader (pPixmap);
FreePicture ((pointer) pPicture, 0);
pPicture = 0;
pPixmap = 0;
}
}
if (maskFormat)
{
x = extents.x1;
y = extents.y1;
CompositePicture (op,
pSrc,
pMask,
pDst,
xSrc + x - xDst,
ySrc + y - yDst,
0, 0,
x, y,
width, height);
FreePicture ((pointer) pMask, (XID) 0);
(*pScreen->DestroyPixmap) (pMaskPixmap);
}
}

View File

@ -636,7 +636,7 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
/* MI rendering routines */ /* MI rendering routines */
ps->Composite = 0; /* requires DDX support */ ps->Composite = 0; /* requires DDX support */
ps->Glyphs = miGlyphs; ps->Glyphs = NULL;
ps->CompositeRects = miCompositeRects; ps->CompositeRects = miCompositeRects;
ps->Trapezoids = miTrapezoids; ps->Trapezoids = miTrapezoids;
ps->Triangles = miTriangles; ps->Triangles = miTriangles;

View File

@ -119,12 +119,6 @@ void
miUnrealizeGlyph (ScreenPtr pScreen, miUnrealizeGlyph (ScreenPtr pScreen,
GlyphPtr glyph); GlyphPtr glyph);
void
miGlyphExtents (int nlist,
GlyphListPtr list,
GlyphPtr *glyphs,
BoxPtr extents);
void void
miGlyphs (CARD8 op, miGlyphs (CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,

View File

@ -1672,24 +1672,6 @@ CompositePicture (CARD8 op,
height); height);
} }
void
CompositeGlyphs (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nlist,
GlyphListPtr lists,
GlyphPtr *glyphs)
{
PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
ValidatePicture (pSrc);
ValidatePicture (pDst);
(*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
}
void void
CompositeRects (CARD8 op, CompositeRects (CARD8 op,
PicturePtr pDst, PicturePtr pDst,

View File

@ -115,7 +115,7 @@ typedef enum _PictFormatShort {
/* 1bpp formats */ /* 1bpp formats */
PICT_a1 = PIXMAN_a1, PICT_a1 = PIXMAN_a1,
PICT_g1 = PIXMAN_g1, PICT_g1 = PIXMAN_g1
} PictFormatShort; } PictFormatShort;
/* /*

View File

@ -342,7 +342,7 @@ typedef struct _PictureScreen {
ValidatePictureProcPtr ValidatePicture; ValidatePictureProcPtr ValidatePicture;
CompositeProcPtr Composite; CompositeProcPtr Composite;
GlyphsProcPtr Glyphs; GlyphsProcPtr Glyphs; /* unused */
CompositeRectsProcPtr CompositeRects; CompositeRectsProcPtr CompositeRects;
DestroyWindowProcPtr DestroyWindow; DestroyWindowProcPtr DestroyWindow;

View File

@ -1170,24 +1170,31 @@ ProcRenderFreeGlyphSet (ClientPtr client)
} }
typedef struct _GlyphNew { typedef struct _GlyphNew {
Glyph id; Glyph id;
GlyphPtr glyph; GlyphPtr glyph;
Bool found;
unsigned char sha1[20];
} GlyphNewRec, *GlyphNewPtr; } GlyphNewRec, *GlyphNewPtr;
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
static int static int
ProcRenderAddGlyphs (ClientPtr client) ProcRenderAddGlyphs (ClientPtr client)
{ {
GlyphSetPtr glyphSet; GlyphSetPtr glyphSet;
REQUEST(xRenderAddGlyphsReq); REQUEST(xRenderAddGlyphsReq);
GlyphNewRec glyphsLocal[NLOCALGLYPH]; GlyphNewRec glyphsLocal[NLOCALGLYPH];
GlyphNewPtr glyphsBase, glyphs; GlyphNewPtr glyphsBase, glyphs, glyph_new;
GlyphPtr glyph;
int remain, nglyphs; int remain, nglyphs;
CARD32 *gids; CARD32 *gids;
xGlyphInfo *gi; xGlyphInfo *gi;
CARD8 *bits; CARD8 *bits;
int size; int size;
int err; int err;
int i, screen;
PicturePtr pSrc = NULL, pDst = NULL;
PixmapPtr pSrcPix = NULL, pDstPix = NULL;
CARD32 component_alpha;
REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
err = dixLookupResource((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, err = dixLookupResource((pointer *)&glyphSet, stuff->glyphset, GlyphSetType,
@ -1203,11 +1210,15 @@ ProcRenderAddGlyphs (ClientPtr client)
if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
return BadAlloc; return BadAlloc;
if (nglyphs <= NLOCALGLYPH) component_alpha = NeedsComponent (glyphSet->format->format);
if (nglyphs <= NLOCALGLYPH) {
memset (glyphsLocal, 0, sizeof (glyphsLocal));
glyphsBase = glyphsLocal; glyphsBase = glyphsLocal;
}
else else
{ {
glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec)); glyphsBase = (GlyphNewPtr) Xcalloc (nglyphs * sizeof (GlyphNewRec));
if (!glyphsBase) if (!glyphsBase)
return BadAlloc; return BadAlloc;
} }
@ -1220,58 +1231,133 @@ ProcRenderAddGlyphs (ClientPtr client)
gi = (xGlyphInfo *) (gids + nglyphs); gi = (xGlyphInfo *) (gids + nglyphs);
bits = (CARD8 *) (gi + nglyphs); bits = (CARD8 *) (gi + nglyphs);
remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
while (remain >= 0 && nglyphs) for (i = 0; i < nglyphs; i++)
{ {
glyph = AllocateGlyph (gi, glyphSet->fdepth); glyph_new = &glyphs[i];
if (!glyph) size = gi[i].height * PixmapBytePad (gi[i].width,
{ glyphSet->format->depth);
err = BadAlloc;
goto bail;
}
glyphs->glyph = glyph;
glyphs->id = *gids;
size = glyph->size - sizeof (xGlyphInfo);
if (remain < size) if (remain < size)
break; break;
memcpy ((CARD8 *) (glyph + 1), bits, size);
err = HashGlyph (&gi[i], bits, size, glyph_new->sha1);
if (err)
goto bail;
glyph_new->glyph = FindGlyphByHash (glyph_new->sha1,
glyphSet->fdepth);
if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph)
{
glyph_new->found = TRUE;
}
else
{
GlyphPtr glyph;
glyph_new->found = FALSE;
glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth);
if (! glyph)
{
err = BadAlloc;
goto bail;
}
for (screen = 0; screen < screenInfo.numScreens; screen++)
{
int width = gi[i].width;
int height = gi[i].height;
int depth = glyphSet->format->depth;
ScreenPtr pScreen;
int error;
pScreen = screenInfo.screens[screen];
pSrcPix = GetScratchPixmapHeader (pScreen,
width, height,
depth, depth,
-1, bits);
if (! pSrcPix)
{
err = BadAlloc;
goto bail;
}
pSrc = CreatePicture (0, &pSrcPix->drawable,
glyphSet->format, 0, NULL,
serverClient, &error);
if (! pSrc)
{
err = BadAlloc;
goto bail;
}
pDstPix = (pScreen->CreatePixmap) (pScreen,
width, height, depth);
GlyphPicture (glyph)[screen] = pDst =
CreatePicture (0, &pDstPix->drawable,
glyphSet->format,
CPComponentAlpha, &component_alpha,
serverClient, &error);
/* The picture takes a reference to the pixmap, so we
drop ours. */
(pScreen->DestroyPixmap) (pDstPix);
if (! pDst)
{
err = BadAlloc;
goto bail;
}
CompositePicture (PictOpSrc,
pSrc,
None,
pDst,
0, 0,
0, 0,
0, 0,
width, height);
FreePicture ((pointer) pSrc, 0);
pSrc = NULL;
FreeScratchPixmapHeader (pSrcPix);
pSrcPix = NULL;
}
memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20);
}
glyph_new->id = gids[i];
if (size & 3) if (size & 3)
size += 4 - (size & 3); size += 4 - (size & 3);
bits += size; bits += size;
remain -= size; remain -= size;
gi++;
gids++;
glyphs++;
nglyphs--;
} }
if (nglyphs || remain) if (remain || i < nglyphs)
{ {
err = BadLength; err = BadLength;
goto bail; goto bail;
} }
nglyphs = stuff->nglyphs;
if (!ResizeGlyphSet (glyphSet, nglyphs)) if (!ResizeGlyphSet (glyphSet, nglyphs))
{ {
err = BadAlloc; err = BadAlloc;
goto bail; goto bail;
} }
glyphs = glyphsBase; for (i = 0; i < nglyphs; i++)
while (nglyphs--) { AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id);
AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
glyphs++;
}
if (glyphsBase != glyphsLocal) if (glyphsBase != glyphsLocal)
Xfree (glyphsBase); Xfree (glyphsBase);
return client->noClientException; return client->noClientException;
bail: bail:
while (glyphs != glyphsBase) if (pSrc)
{ FreePicture ((pointer) pSrc, 0);
--glyphs; if (pSrcPix)
xfree (glyphs->glyph); FreeScratchPixmapHeader (pSrcPix);
} for (i = 0; i < nglyphs; i++)
if (glyphs[i].glyph && ! glyphs[i].found)
xfree (glyphs[i].glyph);
if (glyphsBase != glyphsLocal) if (glyphsBase != glyphsLocal)
Xfree (glyphsBase); Xfree (glyphsBase);
return err; return err;