Fix RENDER issues (bug #7555) and implement RENDER add/remove screen
support (bug #8485).
This commit is contained in:
parent
c92f7bef54
commit
a5fcf1e5e7
|
@ -1007,7 +1007,7 @@ dnl ---------------------------------------------------------------------------
|
||||||
dnl DMX DDX
|
dnl DMX DDX
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether to build Xdmx 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
|
if test "x$DMX" = xauto; then
|
||||||
DMX="$have_dmx"
|
DMX="$have_dmx"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1056,6 +1056,116 @@ static Bool dmxCompareScreens(DMXScreenInfo *new, DMXScreenInfo *old)
|
||||||
return TRUE;
|
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. */
|
/** Reattach previously detached back-end screen. */
|
||||||
int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
|
int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
|
||||||
{
|
{
|
||||||
|
@ -1174,6 +1284,20 @@ int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
|
||||||
/* Create window hierarchy (top down) */
|
/* Create window hierarchy (top down) */
|
||||||
dmxBECreateWindowTree(idx);
|
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 */
|
/* Refresh screen by generating exposure events for all windows */
|
||||||
dmxForceExposures(idx);
|
dmxForceExposures(idx);
|
||||||
|
|
||||||
|
@ -1362,8 +1486,15 @@ static void dmxBEDestroyResources(pointer value, XID id, RESTYPE type,
|
||||||
#ifdef RENDER
|
#ifdef RENDER
|
||||||
} else if ((type & TypeMask) == (PictureType & TypeMask)) {
|
} else if ((type & TypeMask) == (PictureType & TypeMask)) {
|
||||||
PicturePtr pPict = value;
|
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);
|
dmxBEFreePicture((PicturePtr)value);
|
||||||
|
}
|
||||||
} else if ((type & TypeMask) == (GlyphSetType & TypeMask)) {
|
} else if ((type & TypeMask) == (GlyphSetType & TypeMask)) {
|
||||||
dmxBEFreeGlyphSet(pScreen, (GlyphSetPtr)value);
|
dmxBEFreeGlyphSet(pScreen, (GlyphSetPtr)value);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -624,7 +624,7 @@ void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure that the command-line arguments are sane. */
|
/* 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
|
/* Currently it is not possible to support GLX and Render
|
||||||
* extensions with dynamic screen addition/removal due to the
|
* extensions with dynamic screen addition/removal due to the
|
||||||
* state that each extension keeps, which cannot be restored. */
|
* state that each extension keeps, which cannot be restored. */
|
||||||
|
|
|
@ -223,6 +223,36 @@ Bool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet)
|
||||||
return FALSE;
|
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
|
/** 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
|
* 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
|
* 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);
|
ret = dmxSaveRenderVector[stuff->renderReqType](client);
|
||||||
|
|
||||||
if (ret == Success) {
|
if (ret == Success) {
|
||||||
int (*oldErrorHandler)(Display *, XErrorEvent *);
|
|
||||||
GlyphSetPtr glyphSet;
|
GlyphSetPtr glyphSet;
|
||||||
dmxGlyphPrivPtr glyphPriv;
|
dmxGlyphPrivPtr glyphPriv;
|
||||||
int i;
|
int i;
|
||||||
PictFormatPtr pFmt;
|
|
||||||
XRenderPictFormat *pFormat;
|
|
||||||
|
|
||||||
/* Look up glyphSet that was just created ???? */
|
/* Look up glyphSet that was just created ???? */
|
||||||
/* Store glyphsets from backends in glyphSet->devPrivate ????? */
|
/* Store glyphsets from backends in glyphSet->devPrivate ????? */
|
||||||
|
@ -254,21 +281,16 @@ static int dmxProcRenderCreateGlyphSet(ClientPtr client)
|
||||||
MAXSCREENSALLOC_RETURN(glyphPriv->glyphSets, BadAlloc);
|
MAXSCREENSALLOC_RETURN(glyphPriv->glyphSets, BadAlloc);
|
||||||
DMX_SET_GLYPH_PRIV(glyphSet, glyphPriv);
|
DMX_SET_GLYPH_PRIV(glyphSet, glyphPriv);
|
||||||
|
|
||||||
pFmt = SecurityLookupIDByType(client, stuff->format, PictFormatType,
|
|
||||||
DixReadAccess);
|
|
||||||
|
|
||||||
oldErrorHandler = XSetErrorHandler(dmxGlyphErrorHandler);
|
|
||||||
|
|
||||||
for (i = 0; i < dmxNumScreens; i++) {
|
for (i = 0; i < dmxNumScreens; i++) {
|
||||||
DMXScreenInfo *dmxScreen = &dmxScreens[i];
|
DMXScreenInfo *dmxScreen = &dmxScreens[i];
|
||||||
|
int beret;
|
||||||
|
|
||||||
if (!dmxScreen->beDisplay) {
|
if (!dmxScreen->beDisplay) {
|
||||||
glyphPriv->glyphSets[i] = 0;
|
glyphPriv->glyphSets[i] = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFormat = dmxFindFormat(dmxScreen, pFmt);
|
if ((beret = dmxBECreateGlyphSet(i, glyphSet)) != Success) {
|
||||||
if (!pFormat) {
|
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
/* Free the glyph sets we've allocated thus far */
|
/* Free the glyph sets we've allocated thus far */
|
||||||
|
@ -278,30 +300,9 @@ static int dmxProcRenderCreateGlyphSet(ClientPtr client)
|
||||||
/* Free the resource created by render */
|
/* Free the resource created by render */
|
||||||
FreeResource(stuff->gsid, RT_NONE);
|
FreeResource(stuff->gsid, RT_NONE);
|
||||||
|
|
||||||
ret = BadMatch;
|
return beret;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XSetErrorHandler(oldErrorHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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
|
/** Create a picture. This function handles the CreatePicture
|
||||||
* unwrapping/wrapping and calls dmxDoCreatePicture to actually create
|
* unwrapping/wrapping and calls dmxDoCreatePicture to actually create
|
||||||
* the picture on the appropriate screen. */
|
* 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
|
/* The clip has already been changed into a region by the mi
|
||||||
* routine called above.
|
* 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;
|
RegionPtr pClip = pPicture->clientClip;
|
||||||
BoxPtr pBox = REGION_RECTS(pClip);
|
BoxPtr pBox = REGION_RECTS(pClip);
|
||||||
int nBox = REGION_NUM_RECTS(pClip);
|
int nBox = REGION_NUM_RECTS(pClip);
|
||||||
|
|
|
@ -112,7 +112,9 @@ extern void dmxTriFan(CARD8 op,
|
||||||
INT16 xSrc, INT16 ySrc,
|
INT16 xSrc, INT16 ySrc,
|
||||||
int npoint, xPointFixed *points);
|
int npoint, xPointFixed *points);
|
||||||
|
|
||||||
|
extern int dmxBECreateGlyphSet(int idx, GlyphSetPtr glyphSet);
|
||||||
extern Bool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet);
|
extern Bool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet);
|
||||||
|
extern int dmxBECreatePicture(PicturePtr pPicture);
|
||||||
extern Bool dmxBEFreePicture(PicturePtr pPicture);
|
extern Bool dmxBEFreePicture(PicturePtr pPicture);
|
||||||
|
|
||||||
extern int dmxPictPrivateIndex; /**< Index for picture private data */
|
extern int dmxPictPrivateIndex; /**< Index for picture private data */
|
||||||
|
|
Loading…
Reference in New Issue