diff --git a/configure.ac b/configure.ac index 76f5e04..cb9a000 100644 --- a/configure.ac +++ b/configure.ac @@ -882,7 +882,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 diff --git a/hw/dmx/dmxextension.c b/hw/dmx/dmxextension.c index efcaca4..2562f86 100644 --- a/hw/dmx/dmxextension.c +++ b/hw/dmx/dmxextension.c @@ -1056,6 +1056,103 @@ static Bool dmxCompareScreens(DMXScreenI return TRUE; } +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); +} + +static void dmxBERestoreRenderGlyph(pointer value, XID id, pointer n) +{ + int beret, len_images = 0, itr = 0, scrnNum = (int)n; + GlyphSetPtr gs = value; + dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(gs); + DMXScreenInfo *dmxScreen = &dmxScreens[scrnNum]; + + if(glyphPriv->glyphSets[scrnNum]) + { + /*I should only restore glyphs on the monitor we are attaching*/ + return; + } + + /*first we must create the glyph set on the backend. */ + if((beret=dmxBECreateGlyphSet(scrnNum,gs))!=Success) + { + dmxLog(dmxWarning,"\tdmxBERestoreRenderGlyph failed to create glyphset!\n"); + return; + } + + /* Now for the complex part, restore the glyph data */ + GlyphRefPtr table = gs->hash.table; + + /* We need to know how much memory to allocate for this part */ + for(itr=0;itrhash.hashSet->size;itr++) + { + GlyphRefPtr gr = &table[itr]; + GlyphPtr gl = gr->glyph; + + if(!gl || gl==DeletedGlyph) continue; + len_images+=gl->size-sizeof(gl->info); + } + + /* now allocate the memory we need */ + char* images = ALLOCATE_LOCAL(len_images*sizeof(char)); + Glyph* gids = ALLOCATE_LOCAL(gs->hash.tableEntries*sizeof(Glyph)); + XGlyphInfo* glyphs = ALLOCATE_LOCAL(gs->hash.tableEntries*sizeof(XGlyphInfo)); + memset(images,0,len_images*sizeof(char)); + char* pos = images; + int ctr = 0; + + /* fill the allocated memory with the proper data.*/ + for(itr=0;itrhash.hashSet->size;itr++) + { + GlyphRefPtr gr = &table[itr]; + 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,gs->hash.tableEntries,images,len_images); + + /* clean up */ + DEALLOCATE_LOCAL(len_images); + DEALLOCATE_LOCAL(gids); + DEALLOCATE_LOCAL(glyphs); +} + /** Reattach previously detached back-end screen. */ int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr) { @@ -1174,6 +1271,18 @@ int dmxAttachScreen(int idx, DMXScreenAt /* Create window hierarchy (top down) */ dmxBECreateWindowTree(idx); + /* 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); + /* Refresh screen by generating exposure events for all windows */ dmxForceExposures(idx); @@ -1363,7 +1472,16 @@ static void dmxBEDestroyResources(pointe } else if ((type & TypeMask) == (PictureType & TypeMask)) { PicturePtr pPict = value; 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 diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c index 9c5356e..1d3689c 100644 --- a/hw/dmx/dmxinit.c +++ b/hw/dmx/dmxinit.c @@ -624,7 +624,7 @@ void InitOutput(ScreenInfo *pScreenInfo, } /* 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. */ diff --git a/hw/dmx/dmxpict.c b/hw/dmx/dmxpict.c index 9cdd123..5c4c40d 100644 --- a/hw/dmx/dmxpict.c +++ b/hw/dmx/dmxpict.c @@ -223,6 +223,32 @@ Bool dmxBEFreeGlyphSet(ScreenPtr pScreen return FALSE; } +/** + this is the function that shall make the glyphset on the backend. +*/ +int dmxBECreateGlyphSet(int scrn_num,GlyphSetPtr gs) +{ + XRenderPictFormat *pFormat; + DMXScreenInfo *dmxScreen = &dmxScreens[scrn_num]; + dmxGlyphPrivPtr glyphPriv = DMX_GET_GLYPH_PRIV(gs); + PictFormatPtr pFmt = gs->format; + + pFormat = dmxFindFormat(dmxScreen, pFmt); + if (!pFormat) { + return BadMatch; + } + + /* Catch when this fails */ + glyphPriv->glyphSets[scrn_num] + = XRenderCreateGlyphSet(dmxScreen->beDisplay, pFormat); + + 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 @@ -239,8 +265,6 @@ static int dmxProcRenderCreateGlyphSet(C 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,39 +278,20 @@ static int dmxProcRenderCreateGlyphSet(C 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++) { + 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) { - 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 = BadMatch; - break; - } - - /* Catch when this fails */ - glyphPriv->glyphSets[i] - = XRenderCreateGlyphSet(dmxScreen->beDisplay, pFormat); - - if (dmxGlyphLastError) { + if((beret=dmxBECreateGlyphSet(i,glyphSet))!=Success) + { int j; /* Free the glyph sets we've allocated thus far */ @@ -296,8 +301,7 @@ static int dmxProcRenderCreateGlyphSet(C /* Free the resource created by render */ FreeResource(stuff->gsid, RT_NONE); - ret = dmxGlyphLastError; - break; + return beret; } } @@ -753,6 +757,18 @@ void dmxCreatePictureList(WindowPtr pWin } } +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,(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 +869,13 @@ int dmxChangePictureClip(PicturePtr pPic /* 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);