void clientwin_repair(ClientWin *cw) { int nrects, i; XRectangle *rects; XserverRegion rgn = XFixesCreateRegion(cw->mainwin->dpy, 0, 0); XDamageSubtract(cw->mainwin->dpy, cw->damage, None, rgn); rects = XFixesFetchRegion(cw->mainwin->dpy, rgn, &nrects); XFixesDestroyRegion(cw->mainwin->dpy, rgn); for(i = 0; i < nrects; i++) clientwin_repaint(cw, &rects[i]); if(rects) XFree(rects); cw->damaged = False; }
/* * Updates visible regions for given spu window. * Returns GL_TRUE if regions changed since last call, GL_FALSE otherwise. */ GLboolean stubUpdateWindowVisibileRegions(WindowInfo *pWindow) { XserverRegion xreg; int cRects, i; XRectangle *pXRects; GLint* pGLRects; Display *dpy; bool bNoUpdate = false; if (!stub.bXExtensionsChecked) { stubCheckXExtensions(pWindow); if (!stub.trackWindowVisibleRgn) { return GL_FALSE; } } dpy = stubGetWindowDisplay(pWindow); /*@todo see comment regarding size/position updates and XSync, same applies to those functions but * it seems there's no way to get even based updates for this. Or I've failed to find the appropriate extension. */ XLOCK(dpy); xreg = XCompositeCreateRegionFromBorderClip(dpy, pWindow->drawable); pXRects = XFixesFetchRegion(dpy, xreg, &cRects); XFixesDestroyRegion(dpy, xreg); XUNLOCK(dpy); /* Check for compiz main window */ if (!pWindow->pVisibleRegions && !cRects) { #ifdef VBOX_TEST_MEGOO XWindowAttributes attr; XLOCK(dpy); XSync(dpy, false); XGetWindowAttributes(dpy, pWindow->drawable, &attr); XUNLOCK(dpy); bNoUpdate = attr.override_redirect; #else bNoUpdate = true; #endif } if (!bNoUpdate && (!pWindow->pVisibleRegions || pWindow->cVisibleRegions!=cRects || (pWindow->pVisibleRegions && crMemcmp(pWindow->pVisibleRegions, pXRects, cRects * sizeof(XRectangle))))) { if (pWindow->pVisibleRegions) { XFree(pWindow->pVisibleRegions); } pWindow->pVisibleRegions = pXRects; pWindow->cVisibleRegions = cRects; pGLRects = crAlloc(4*cRects*sizeof(GLint)); if (!pGLRects) { crWarning("stubUpdateWindowVisibileRegions: failed to allocate %lu bytes", (unsigned long)(4*cRects*sizeof(GLint))); return GL_FALSE; } //crDebug("Got %i rects.", cRects); for (i=0; i<cRects; ++i) { pGLRects[4*i+0] = pXRects[i].x; pGLRects[4*i+1] = pXRects[i].y; pGLRects[4*i+2] = pXRects[i].x+pXRects[i].width; pGLRects[4*i+3] = pXRects[i].y+pXRects[i].height; //crDebug("Rect[%i]=(%i,%i,%i,%i)", i, pGLRects[4*i+0], pGLRects[4*i+1], pGLRects[4*i+2], pGLRects[4*i+3]); } crDebug("Dispatched WindowVisibleRegion (%i, cRects=%i)", pWindow->spuWindow, cRects); stub.spuDispatch.WindowVisibleRegion(pWindow->spuWindow, cRects, pGLRects); crFree(pGLRects); return GL_TRUE; } else { XFree(pXRects); } return GL_FALSE; }