Fix RENDER issues (bug #7555) and implement RENDER add/remove screen
support (bug #8485).
This commit is contained in:
parent
7d927a6f6a
commit
c10663e9cc
|
@ -936,7 +936,7 @@ dnl ---------------------------------------------------------------------------
|
|||
dnl DMX DDX
|
||||
|
||||
AC_MSG_CHECKING([whether to build Xdmx DDX])
|
||||
PKG_CHECK_MODULES([DMXMODULES], [xmuu xext x11 xrender xfont xi dmxproto xau $XDMCP_MODULES], [have_dmx=yes], [have_dmx=no])
|
||||
PKG_CHECK_MODULES([DMXMODULES], [xmuu xext x11 xrender xfixes xfont xi dmxproto xau $XDMCP_MODULES], [have_dmx=yes], [have_dmx=no])
|
||||
if test "x$DMX" = xauto; then
|
||||
DMX="$have_dmx"
|
||||
fi
|
||||
|
|
|
@ -1056,6 +1056,116 @@ static Bool dmxCompareScreens(DMXScreenInfo *new, DMXScreenInfo *old)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef RENDER
|
||||
/** Restore Render's picture */
|
||||
static void dmxBERestoreRenderPict(pointer value, XID id, pointer n)
|
||||
{
|
||||
PicturePtr pPicture = value; /* The picture */
|
||||
DrawablePtr pDraw = pPicture->pDrawable; /* The picture's drawable */
|
||||
int scrnNum = (int)n;
|
||||
|
||||
if (pDraw->pScreen->myNum != scrnNum) {
|
||||
/* Picture not on the screen we are restoring*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (pDraw->type == DRAWABLE_PIXMAP) {
|
||||
PixmapPtr pPixmap = (PixmapPtr)pDraw;
|
||||
|
||||
/* Create and restore the pixmap drawable */
|
||||
dmxBECreatePixmap(pPixmap);
|
||||
dmxBERestorePixmap(pPixmap);
|
||||
}
|
||||
|
||||
dmxBECreatePicture(pPicture);
|
||||
}
|
||||
|
||||
/** Restore Render's glyphs */
|
||||
static void dmxBERestoreRenderGlyph(pointer value, XID id, pointer n)
|
||||
{
|
||||
GlyphSetPtr glyphSet = value;
|
||||
int scrnNum = (int)n;
|
||||
dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[scrnNum];
|
||||
GlyphRefPtr table;
|
||||
char *images;
|
||||
Glyph *gids;
|
||||
XGlyphInfo *glyphs;
|
||||
char *pos;
|
||||
int beret;
|
||||
int len_images = 0;
|
||||
int i;
|
||||
int ctr;
|
||||
|
||||
if (glyphPriv->glyphSets[scrnNum]) {
|
||||
/* Only restore glyphs on the screen we are attaching */
|
||||
return;
|
||||
}
|
||||
|
||||
/* First we must create the glyph set on the backend. */
|
||||
if ((beret = dmxBECreateGlyphSet(scrnNum, glyphSet)) != Success) {
|
||||
dmxLog(dmxWarning,
|
||||
"\tdmxBERestoreRenderGlyph failed to create glyphset!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now for the complex part, restore the glyph data */
|
||||
table = glyphSet->hash.table;
|
||||
|
||||
/* We need to know how much memory to allocate for this part */
|
||||
for (i = 0; i < glyphSet->hash.hashSet->size; i++) {
|
||||
GlyphRefPtr gr = &table[i];
|
||||
GlyphPtr gl = gr->glyph;
|
||||
|
||||
if (!gl || gl == DeletedGlyph) continue;
|
||||
len_images += gl->size - sizeof(gl->info);
|
||||
}
|
||||
|
||||
/* Now allocate the memory we need */
|
||||
images = ALLOCATE_LOCAL(len_images*sizeof(char));
|
||||
gids = ALLOCATE_LOCAL(glyphSet->hash.tableEntries*sizeof(Glyph));
|
||||
glyphs = ALLOCATE_LOCAL(glyphSet->hash.tableEntries*sizeof(XGlyphInfo));
|
||||
|
||||
memset(images, 0, len_images * sizeof(char));
|
||||
pos = images;
|
||||
ctr = 0;
|
||||
|
||||
/* Fill the allocated memory with the proper data */
|
||||
for (i = 0; i < glyphSet->hash.hashSet->size; i++) {
|
||||
GlyphRefPtr gr = &table[i];
|
||||
GlyphPtr gl = gr->glyph;
|
||||
|
||||
if (!gl || gl == DeletedGlyph) continue;
|
||||
|
||||
/* First lets put the data into gids */
|
||||
gids[ctr] = gr->signature;
|
||||
|
||||
/* Next do the glyphs data structures */
|
||||
glyphs[ctr].width = gl->info.width;
|
||||
glyphs[ctr].height = gl->info.height;
|
||||
glyphs[ctr].x = gl->info.x;
|
||||
glyphs[ctr].y = gl->info.y;
|
||||
glyphs[ctr].xOff = gl->info.xOff;
|
||||
glyphs[ctr].yOff = gl->info.yOff;
|
||||
|
||||
/* Copy the images from the DIX's data into the buffer */
|
||||
memcpy(pos, gl+1, gl->size - sizeof(gl->info));
|
||||
pos += gl->size - sizeof(gl->info);
|
||||
ctr++;
|
||||
}
|
||||
|
||||
/* Now restore the glyph data */
|
||||
XRenderAddGlyphs(dmxScreen->beDisplay, glyphPriv->glyphSets[scrnNum],
|
||||
gids,glyphs, glyphSet->hash.tableEntries, images,
|
||||
len_images);
|
||||
|
||||
/* Clean up */
|
||||
DEALLOCATE_LOCAL(len_images);
|
||||
DEALLOCATE_LOCAL(gids);
|
||||
DEALLOCATE_LOCAL(glyphs);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Reattach previously detached back-end screen. */
|
||||
int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
|
||||
{
|
||||
|
@ -1174,6 +1284,20 @@ int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
|
|||
/* Create window hierarchy (top down) */
|
||||
dmxBECreateWindowTree(idx);
|
||||
|
||||
#ifdef RENDER
|
||||
/* Restore the picture state for RENDER */
|
||||
for (i = currentMaxClients; --i >= 0; )
|
||||
if (clients[i])
|
||||
FindClientResourcesByType(clients[i],PictureType,
|
||||
dmxBERestoreRenderPict,(pointer)idx);
|
||||
|
||||
/* Restore the glyph state for RENDER */
|
||||
for (i = currentMaxClients; --i >= 0; )
|
||||
if (clients[i])
|
||||
FindClientResourcesByType(clients[i],GlyphSetType,
|
||||
dmxBERestoreRenderGlyph,(pointer)idx);
|
||||
#endif
|
||||
|
||||
/* Refresh screen by generating exposure events for all windows */
|
||||
dmxForceExposures(idx);
|
||||
|
||||
|
@ -1362,8 +1486,15 @@ static void dmxBEDestroyResources(pointer value, XID id, RESTYPE type,
|
|||
#ifdef RENDER
|
||||
} else if ((type & TypeMask) == (PictureType & TypeMask)) {
|
||||
PicturePtr pPict = value;
|
||||
if (pPict->pDrawable->pScreen->myNum == scrnNum)
|
||||
if (pPict->pDrawable->pScreen->myNum == scrnNum) {
|
||||
/* Free the pixmaps on the backend if needed */
|
||||
if (pPict->pDrawable->type == DRAWABLE_PIXMAP) {
|
||||
PixmapPtr pPixmap = (PixmapPtr)(pPict->pDrawable);
|
||||
dmxBESavePixmap(pPixmap);
|
||||
dmxBEFreePixmap(pPixmap);
|
||||
}
|
||||
dmxBEFreePicture((PicturePtr)value);
|
||||
}
|
||||
} else if ((type & TypeMask) == (GlyphSetType & TypeMask)) {
|
||||
dmxBEFreeGlyphSet(pScreen, (GlyphSetPtr)value);
|
||||
#endif
|
||||
|
|
|
@ -624,7 +624,7 @@ void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* Make sure that the command-line arguments are sane. */
|
||||
if (dmxAddRemoveScreens && (!noRenderExtension || dmxGLXProxy)) {
|
||||
if (dmxAddRemoveScreens && dmxGLXProxy) {
|
||||
/* Currently it is not possible to support GLX and Render
|
||||
* extensions with dynamic screen addition/removal due to the
|
||||
* state that each extension keeps, which cannot be restored. */
|
||||
|
|
|
@ -223,6 +223,36 @@ Bool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/** Create \a glyphSet on the backend screen number \a idx. */
|
||||
int dmxBECreateGlyphSet(int idx, GlyphSetPtr glyphSet)
|
||||
{
|
||||
XRenderPictFormat *pFormat;
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
|
||||
dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
|
||||
PictFormatPtr pFmt = glyphSet->format;
|
||||
int (*oldErrorHandler)(Display *, XErrorEvent *);
|
||||
|
||||
pFormat = dmxFindFormat(dmxScreen, pFmt);
|
||||
if (!pFormat) {
|
||||
return BadMatch;
|
||||
}
|
||||
|
||||
dmxGlyphLastError = 0;
|
||||
oldErrorHandler = XSetErrorHandler(dmxGlyphErrorHandler);
|
||||
|
||||
/* Catch when this fails */
|
||||
glyphPriv->glyphSets[idx]
|
||||
= XRenderCreateGlyphSet(dmxScreen->beDisplay, pFormat);
|
||||
|
||||
XSetErrorHandler(oldErrorHandler);
|
||||
|
||||
if (dmxGlyphLastError) {
|
||||
return dmxGlyphLastError;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
/** Create a Glyph Set on each screen. Save the glyphset ID from each
|
||||
* screen in the Glyph Set's private structure. Fail if the format
|
||||
* requested is not available or if the Glyph Set cannot be created on
|
||||
|
@ -235,12 +265,9 @@ static int dmxProcRenderCreateGlyphSet(ClientPtr client)
|
|||
ret = dmxSaveRenderVector[stuff->renderReqType](client);
|
||||
|
||||
if (ret == Success) {
|
||||
int (*oldErrorHandler)(Display *, XErrorEvent *);
|
||||
GlyphSetPtr glyphSet;
|
||||
dmxGlyphPrivPtr glyphPriv;
|
||||
int i;
|
||||
PictFormatPtr pFmt;
|
||||
XRenderPictFormat *pFormat;
|
||||
|
||||
/* Look up glyphSet that was just created ???? */
|
||||
/* Store glyphsets from backends in glyphSet->devPrivate ????? */
|
||||
|
@ -254,21 +281,16 @@ static int dmxProcRenderCreateGlyphSet(ClientPtr client)
|
|||
MAXSCREENSALLOC_RETURN(glyphPriv->glyphSets, BadAlloc);
|
||||
DMX_SET_GLYPH_PRIV(glyphSet, glyphPriv);
|
||||
|
||||
pFmt = SecurityLookupIDByType(client, stuff->format, PictFormatType,
|
||||
SecurityReadAccess);
|
||||
|
||||
oldErrorHandler = XSetErrorHandler(dmxGlyphErrorHandler);
|
||||
|
||||
for (i = 0; i < dmxNumScreens; i++) {
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[i];
|
||||
int beret;
|
||||
|
||||
if (!dmxScreen->beDisplay) {
|
||||
glyphPriv->glyphSets[i] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
pFormat = dmxFindFormat(dmxScreen, pFmt);
|
||||
if (!pFormat) {
|
||||
if ((beret = dmxBECreateGlyphSet(i, glyphSet)) != Success) {
|
||||
int j;
|
||||
|
||||
/* Free the glyph sets we've allocated thus far */
|
||||
|
@ -278,30 +300,9 @@ static int dmxProcRenderCreateGlyphSet(ClientPtr client)
|
|||
/* Free the resource created by render */
|
||||
FreeResource(stuff->gsid, RT_NONE);
|
||||
|
||||
ret = BadMatch;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Catch when this fails */
|
||||
glyphPriv->glyphSets[i]
|
||||
= XRenderCreateGlyphSet(dmxScreen->beDisplay, pFormat);
|
||||
|
||||
if (dmxGlyphLastError) {
|
||||
int j;
|
||||
|
||||
/* Free the glyph sets we've allocated thus far */
|
||||
for (j = 0; j < i; j++)
|
||||
dmxBEFreeGlyphSet(screenInfo.screens[j], glyphSet);
|
||||
|
||||
/* Free the resource created by render */
|
||||
FreeResource(stuff->gsid, RT_NONE);
|
||||
|
||||
ret = dmxGlyphLastError;
|
||||
break;
|
||||
return beret;
|
||||
}
|
||||
}
|
||||
|
||||
XSetErrorHandler(oldErrorHandler);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -753,6 +754,20 @@ void dmxCreatePictureList(WindowPtr pWindow)
|
|||
}
|
||||
}
|
||||
|
||||
/** Create \a pPicture on the backend. */
|
||||
int dmxBECreatePicture(PicturePtr pPicture)
|
||||
{
|
||||
dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
|
||||
|
||||
/* Create picutre on BE */
|
||||
pPictPriv->pict = dmxDoCreatePicture(pPicture);
|
||||
|
||||
/* Flush changes to the backend server */
|
||||
dmxValidatePicture(pPicture, (1 << (CPLastBit+1)) - 1);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
/** Create a picture. This function handles the CreatePicture
|
||||
* unwrapping/wrapping and calls dmxDoCreatePicture to actually create
|
||||
* the picture on the appropriate screen. */
|
||||
|
@ -853,7 +868,11 @@ int dmxChangePictureClip(PicturePtr pPicture, int clipType,
|
|||
/* The clip has already been changed into a region by the mi
|
||||
* routine called above.
|
||||
*/
|
||||
if (pPicture->clientClip) {
|
||||
if (clipType == CT_NONE) {
|
||||
/* Disable clipping, show all */
|
||||
XFixesSetPictureClipRegion(dmxScreen->beDisplay,
|
||||
pPictPriv->pict, 0, 0, None);
|
||||
} else if (pPicture->clientClip) {
|
||||
RegionPtr pClip = pPicture->clientClip;
|
||||
BoxPtr pBox = REGION_RECTS(pClip);
|
||||
int nBox = REGION_NUM_RECTS(pClip);
|
||||
|
|
|
@ -112,7 +112,9 @@ extern void dmxTriFan(CARD8 op,
|
|||
INT16 xSrc, INT16 ySrc,
|
||||
int npoint, xPointFixed *points);
|
||||
|
||||
extern int dmxBECreateGlyphSet(int idx, GlyphSetPtr glyphSet);
|
||||
extern Bool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet);
|
||||
extern int dmxBECreatePicture(PicturePtr pPicture);
|
||||
extern Bool dmxBEFreePicture(PicturePtr pPicture);
|
||||
|
||||
extern int dmxPictPrivateIndex; /**< Index for picture private data */
|
||||
|
|
Loading…
Reference in New Issue
Block a user