static void miTreeObscured( WindowPtr pParent ) { WindowPtr pChild; int oldVis; pChild = pParent; while (1) { if (pChild->viewable) { oldVis = pChild->visibility; if (oldVis != (pChild->visibility = VisibilityFullyObscured) && ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask)) SendVisibilityNotify(pChild); if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pParent)) pChild = pChild->parent; if (pChild == pParent) break; pChild = pChild->nextSib; } }
void miWindowExposures(WindowPtr pWin, RegionPtr prgn) { RegionPtr exposures = prgn; if (prgn && !RegionNil(prgn)) { RegionRec expRec; int clientInterested = (pWin->eventMask | wOtherEventMasks(pWin)) & ExposureMask; if (clientInterested && (RegionNumRects(prgn) > RECTLIMIT)) { /* * If we have LOTS of rectangles, we decide to take the extents * and force an exposure on that. This should require much less * work overall, on both client and server. This is cheating, but * isn't prohibited by the protocol ("spontaneous combustion" :-). */ BoxRec box = *RegionExtents(prgn); exposures = &expRec; RegionInit(exposures, &box, 1); RegionReset(prgn, &box); /* miPaintWindow doesn't clip, so we have to */ RegionIntersect(prgn, prgn, &pWin->clipList); } pWin->drawable.pScreen->PaintWindow(pWin, prgn, PW_BACKGROUND); if (clientInterested) miSendExposures(pWin, exposures, pWin->drawable.x, pWin->drawable.y); if (exposures == &expRec) RegionUninit(exposures); RegionEmpty(prgn); } }
/* *----------------------------------------------------------------------- * miComputeClips -- * Recompute the clipList, borderClip, exposed and borderExposed * regions for pParent and its children. Only viewable windows are * taken into account. * * Results: * None. * * Side Effects: * clipList, borderClip, exposed and borderExposed are altered. * A VisibilityNotify event may be generated on the parent window. * *----------------------------------------------------------------------- */ static void miComputeClips ( WindowPtr pParent, ScreenPtr pScreen, RegionPtr universe, VTKind kind, RegionPtr exposed ) /* for intermediate calculations */ { int dx, dy; RegionRec childUniverse; WindowPtr pChild; int oldVis, newVis; BoxRec borderSize; RegionRec childUnion; Bool overlap; RegionPtr borderVisible; /* * Figure out the new visibility of this window. * The extent of the universe should be the same as the extent of * the borderSize region. If the window is unobscured, this rectangle * will be completely inside the universe (the universe will cover it * completely). If the window is completely obscured, none of the * universe will cover the rectangle. */ borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent); borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent); dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent); if (dx > 32767) dx = 32767; borderSize.x2 = dx; dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent); if (dy > 32767) dy = 32767; borderSize.y2 = dy; #ifdef COMPOSITE /* * In redirected drawing case, reset universe to borderSize */ if (pParent->redirectDraw != RedirectDrawNone) { if (miSetRedirectBorderClipProc) { if (TreatAsTransparent (pParent)) RegionEmpty(universe); (*miSetRedirectBorderClipProc) (pParent, universe); } RegionCopy(universe, &pParent->borderSize); } #endif oldVis = pParent->visibility; switch (RegionContainsRect(universe, &borderSize)) { case rgnIN: newVis = VisibilityUnobscured; break; case rgnPART: newVis = VisibilityPartiallyObscured; { RegionPtr pBounding; if ((pBounding = wBoundingShape (pParent))) { switch (miShapedWindowIn (universe, pBounding, &borderSize, pParent->drawable.x, pParent->drawable.y)) { case rgnIN: newVis = VisibilityUnobscured; break; case rgnOUT: newVis = VisibilityFullyObscured; break; } } } break; default: newVis = VisibilityFullyObscured; break; } pParent->visibility = newVis; if (oldVis != newVis && ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) SendVisibilityNotify(pParent); dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x; dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y; /* * avoid computations when dealing with simple operations */ switch (kind) { case VTMap: case VTStack: case VTUnmap: break; case VTMove: if ((oldVis == newVis) && ((oldVis == VisibilityFullyObscured) || (oldVis == VisibilityUnobscured))) { pChild = pParent; while (1) { if (pChild->viewable) { if (pChild->visibility != VisibilityFullyObscured) { RegionTranslate(&pChild->borderClip, dx, dy); RegionTranslate(&pChild->clipList, dx, dy); pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; if (pScreen->ClipNotify) (* pScreen->ClipNotify) (pChild, dx, dy); } if (pChild->valdata) { RegionNull(&pChild->valdata->after.borderExposed); if (HasParentRelativeBorder(pChild)) { RegionSubtract(&pChild->valdata->after.borderExposed, &pChild->borderClip, &pChild->winSize); } RegionNull(&pChild->valdata->after.exposed); } if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pParent)) pChild = pChild->parent; if (pChild == pParent) break; pChild = pChild->nextSib; } return; } /* fall through */ default: /* * To calculate exposures correctly, we have to translate the old * borderClip and clipList regions to the window's new location so there * is a correspondence between pieces of the new and old clipping regions. */ if (dx || dy) { /* * We translate the old clipList because that will be exposed or copied * if gravity is right. */ RegionTranslate(&pParent->borderClip, dx, dy); RegionTranslate(&pParent->clipList, dx, dy); } break; case VTBroken: RegionEmpty(&pParent->borderClip); RegionEmpty(&pParent->clipList); break; } borderVisible = pParent->valdata->before.borderVisible; RegionNull(&pParent->valdata->after.borderExposed); RegionNull(&pParent->valdata->after.exposed); /* * Since the borderClip must not be clipped by the children, we do * the border exposure first... * * 'universe' is the window's borderClip. To figure the exposures, remove * the area that used to be exposed from the new. * This leaves a region of pieces that weren't exposed before. */ if (HasBorder (pParent)) { if (borderVisible) { /* * when the border changes shape, the old visible portions * of the border will be saved by DIX in borderVisible -- * use that region and destroy it */ RegionSubtract(exposed, universe, borderVisible); RegionDestroy(borderVisible); } else { RegionSubtract(exposed, universe, &pParent->borderClip); } if (HasParentRelativeBorder(pParent) && (dx || dy)) RegionSubtract(&pParent->valdata->after.borderExposed, universe, &pParent->winSize); else RegionSubtract(&pParent->valdata->after.borderExposed, exposed, &pParent->winSize); RegionCopy(&pParent->borderClip, universe); /* * To get the right clipList for the parent, and to make doubly sure * that no child overlaps the parent's border, we remove the parent's * border from the universe before proceeding. */ RegionIntersect(universe, universe, &pParent->winSize); } else RegionCopy(&pParent->borderClip, universe); if ((pChild = pParent->firstChild) && pParent->mapped) { RegionNull(&childUniverse); RegionNull(&childUnion); if ((pChild->drawable.y < pParent->lastChild->drawable.y) || ((pChild->drawable.y == pParent->lastChild->drawable.y) && (pChild->drawable.x < pParent->lastChild->drawable.x))) { for (; pChild; pChild = pChild->nextSib) { if (pChild->viewable && !TreatAsTransparent(pChild)) RegionAppend(&childUnion, &pChild->borderSize); } } else { for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) { if (pChild->viewable && !TreatAsTransparent(pChild)) RegionAppend(&childUnion, &pChild->borderSize); } } RegionValidate(&childUnion, &overlap); for (pChild = pParent->firstChild; pChild; pChild = pChild->nextSib) { if (pChild->viewable) { /* * If the child is viewable, we want to remove its extents * from the current universe, but we only re-clip it if * it's been marked. */ if (pChild->valdata) { /* * Figure out the new universe from the child's * perspective and recurse. */ RegionIntersect(&childUniverse, universe, &pChild->borderSize); miComputeClips (pChild, pScreen, &childUniverse, kind, exposed); } /* * Once the child has been processed, we remove its extents * from the current universe, thus denying its space to any * other sibling. */ if (overlap && !TreatAsTransparent (pChild)) RegionSubtract(universe, universe, &pChild->borderSize); } } if (!overlap) RegionSubtract(universe, universe, &childUnion); RegionUninit(&childUnion); RegionUninit(&childUniverse); } /* if any children */ /* * 'universe' now contains the new clipList for the parent window. * * To figure the exposure of the window we subtract the old clip from the * new, just as for the border. */ if (oldVis == VisibilityFullyObscured || oldVis == VisibilityNotViewable) { RegionCopy(&pParent->valdata->after.exposed, universe); } else if (newVis != VisibilityFullyObscured && newVis != VisibilityNotViewable) { RegionSubtract(&pParent->valdata->after.exposed, universe, &pParent->clipList); } /* HACK ALERT - copying contents of regions, instead of regions */ { RegionRec tmp; tmp = pParent->clipList; pParent->clipList = *universe; *universe = tmp; } #ifdef NOTDEF RegionCopy(&pParent->clipList, universe); #endif pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; if (pScreen->ClipNotify) (* pScreen->ClipNotify) (pParent, dx, dy); }
int LbxSendConnSetup(ClientPtr client, char *reason) { int dlength; int i, ndex, lim, wndex; CARD32 dataBuf[16]; xLbxConnSetupPrefix csp; NewClientInfoRec nci; LbxProxyPtr proxy = LbxProxy(client); if (reason) { SendConnSetup(client, reason); LbxForceOutput(proxy); /* expedient to avoid another state variable */ return (client->noClientException); } IncrementClientCount(); client->requestVector = client->swapped ? SwappedProcVector : ProcVector; client->sequence = 0; dataBuf[0] = client->clientAsMask; csp.success = TRUE; csp.majorVersion = connSetupPrefix.majorVersion; csp.minorVersion = connSetupPrefix.minorVersion; csp.tag = 0; #ifdef XAPPGROUP if (!client->appgroup) { #endif csp.changeType = 1; /* LbxNormalDeltas */ csp.length = 2 + /* tag + resource-id-base */ screenInfo.numScreens; /* input-mask per screen */ wndex = 0; ndex = 1; lim = screenInfo.numScreens; #ifdef XAPPGROUP } else { csp.changeType = 2; /* LbxAppGroupDeltas */ csp.length = 7 + /* tag, res-id-base, root, visual, colormap, b&w-pix */ 1 + screenInfo.numScreens - screenInfo.numVideoScreens; XagGetDeltaInfo (client, &dataBuf[1]); for (i = 0; i < MAXSCREENS; i++) { if ((CARD32) WindowTable[i]->drawable.id == dataBuf[1]) { dataBuf[6] = WindowTable[i]->eventMask | wOtherEventMasks(WindowTable[i]); break; } } wndex = screenInfo.numVideoScreens; ndex = 7; lim = screenInfo.numScreens - screenInfo.numVideoScreens; } #endif for (i = 0; i < lim; i++, ndex++, wndex++) { dataBuf[ndex] = WindowTable[wndex]->eventMask | wOtherEventMasks(WindowTable[wndex]); } dlength = (csp.length - 1) << 2; if (LbxProxyClient(proxy)->swapped) { swaps(&csp.length, i); } if (client->swapped) { LbxWriteSConnSetupPrefix(client, &csp); SwapLongs(dataBuf, (1 + screenInfo.numScreens)); WriteToClient(client, dlength, (pointer) dataBuf); } else { WriteToClient(client, sizeof(xLbxConnSetupPrefix), (char *) &csp); WriteToClient(client, dlength, (pointer) dataBuf); } LbxForceOutput(proxy); /* expedient to avoid another state variable */ client->clientState = ClientStateRunning; if (ClientStateCallback) { if (LbxProxyClient(proxy)->swapped != client->swapped) { swaps(&csp.length, i); } nci.client = client; nci.prefix = (xConnSetupPrefix*) &csp; nci.setup = (xConnSetup *) ConnectionInfo; CallCallbacks(&ClientStateCallback, (pointer) &nci); } return client->noClientException; }