Exemple #1
0
/*****
 *  miHandleValidateExposures(pWin)
 *    starting at pWin, draw background in any windows that have exposure
 *    regions, translate the regions, restore any backing store,
 *    and then send any regions still exposed to the client
 *****/
void
miHandleValidateExposures(WindowPtr pWin)
{
    WindowPtr pChild;
    ValidatePtr val;
    WindowExposuresProcPtr WindowExposures;

    pChild = pWin;
    WindowExposures = pChild->drawable.pScreen->WindowExposures;
    while (1) {
        if ((val = pChild->valdata)) {
            if (RegionNotEmpty(&val->after.borderExposed))
                miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER);
            RegionUninit(&val->after.borderExposed);
            (*WindowExposures) (pChild, &val->after.exposed, NullRegion);
            RegionUninit(&val->after.exposed);
            free(val);
            pChild->valdata = NULL;
            if (pChild->firstChild) {
                pChild = pChild->firstChild;
                continue;
            }
        }
        while (!pChild->nextSib && (pChild != pWin))
            pChild = pChild->parent;
        if (pChild == pWin)
            break;
        pChild = pChild->nextSib;
    }
}
Exemple #2
0
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;

            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);
        }
        miPaintWindow(pWin, prgn, PW_BACKGROUND);
        if (clientInterested)
            miSendExposures(pWin, exposures,
                            pWin->drawable.x, pWin->drawable.y);
        if (exposures == &expRec)
            RegionUninit(exposures);
        RegionEmpty(prgn);
    }
}
Exemple #3
0
void
miClearToBackground(WindowPtr pWin,
                    int x, int y, int w, int h, Bool generateExposures)
{
    BoxRec box;
    RegionRec reg;
    BoxPtr extents;
    int x1, y1, x2, y2;

    /* compute everything using ints to avoid overflow */

    x1 = pWin->drawable.x + x;
    y1 = pWin->drawable.y + y;
    if (w)
        x2 = x1 + (int) w;
    else
        x2 = x1 + (int) pWin->drawable.width - (int) x;
    if (h)
        y2 = y1 + h;
    else
        y2 = y1 + (int) pWin->drawable.height - (int) y;

    extents = &pWin->clipList.extents;

    /* clip the resulting rectangle to the window clipList extents.  This
     * makes sure that the result will fit in a box, given that the
     * screen is < 32768 on a side.
     */

    if (x1 < extents->x1)
        x1 = extents->x1;
    if (x2 > extents->x2)
        x2 = extents->x2;
    if (y1 < extents->y1)
        y1 = extents->y1;
    if (y2 > extents->y2)
        y2 = extents->y2;

    if (x2 <= x1 || y2 <= y1) {
        x2 = x1 = 0;
        y2 = y1 = 0;
    }

    box.x1 = x1;
    box.x2 = x2;
    box.y1 = y1;
    box.y2 = y2;

    RegionInit(&reg, &box, 1);

    RegionIntersect(&reg, &reg, &pWin->clipList);
    if (generateExposures)
        (*pWin->drawable.pScreen->WindowExposures) (pWin, &reg, NULL);
    else if (pWin->backgroundState != None)
        miPaintWindow(pWin, &reg, PW_BACKGROUND);
    RegionUninit(&reg);
}
Exemple #4
0
void
winDoRandRScreenSetSize (ScreenPtr  pScreen,
                         CARD16	    width,
                         CARD16	    height,
                         CARD32	    mmWidth,
                         CARD32	    mmHeight)
{
  winScreenPriv(pScreen);
  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
  WindowPtr pRoot = pScreen->root;

  // Prevent screen updates while we change things around
  SetRootClip(pScreen, FALSE);

  /* Update the screen size as requested */
  pScreenInfo->dwWidth = width;
  pScreenInfo->dwHeight = height;

  /* Reallocate the framebuffer used by the drawing engine */
  (*pScreenPriv->pwinFreeFB)(pScreen);
  if (!(*pScreenPriv->pwinAllocateFB)(pScreen))
    {
      ErrorF ("winDoRandRScreenSetSize - Could not reallocate framebuffer\n");
    }

  pScreen->width = width;
  pScreen->height = height;
  pScreen->mmWidth = mmWidth;
  pScreen->mmHeight = mmHeight;

  /* Update the screen pixmap to point to the new framebuffer */
  winUpdateFBPointer(pScreen, pScreenInfo->pfb);

  // pScreen->devPrivate == pScreen->GetScreenPixmap(screen) ?
  // resize the root window
  //pScreen->ResizeWindow(pRoot, 0, 0, width, height, NULL);
  // does this emit a ConfigureNotify??

  // Restore the ability to update screen, now with new dimensions
  SetRootClip(pScreen, TRUE);

  // and arrange for it to be repainted
  miPaintWindow(pRoot, &pRoot->borderClip,  PW_BACKGROUND);

  /* Indicate that a screen size change took place */
  RRScreenSizeNotify(pScreen);
}
Exemple #5
0
static void expose_1 (WindowPtr pWin) {
    WindowPtr pChild;
    
    if (!pWin->realized)
        return;
    
    miPaintWindow(pWin, &pWin->borderClip, PW_BACKGROUND);
    
    /* FIXME: comments in windowstr.h indicate that borderClip doesn't
     include subwindow visibility. But I'm not so sure.. so we may
     be exposing too much.. */
    
    miSendExposures (pWin, &pWin->borderClip,
                     pWin->drawable.x, pWin->drawable.y);
    
    for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib)
        expose_1 (pChild);
}
Exemple #6
0
RegionPtr
miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
                  GCPtr pGC, int srcx, int srcy, int width, int height,
                  int dstx, int dsty, unsigned long plane)
{
    RegionPtr prgnSrcClip;      /* drawable-relative source clip */
    RegionRec rgnSrcRec;
    RegionPtr prgnDstClip;      /* drawable-relative dest clip */
    RegionRec rgnDstRec;
    BoxRec srcBox;              /* unclipped source */
    RegionRec rgnExposed;       /* exposed region, calculated source-
                                   relative, made dst relative to
                                   intersect with visible parts of
                                   dest and send events to client, 
                                   and then screen relative to paint 
                                   the window background
                                 */
    WindowPtr pSrcWin;
    BoxRec expBox;
    Bool extents;

    /* avoid work if we can */
    if (!pGC->graphicsExposures &&
        (pDstDrawable->type == DRAWABLE_PIXMAP) &&
        ((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
         (((WindowPtr) pSrcDrawable)->backStorage == NULL)))
        return NULL;

    srcBox.x1 = srcx;
    srcBox.y1 = srcy;
    srcBox.x2 = srcx + width;
    srcBox.y2 = srcy + height;

    if (pSrcDrawable->type != DRAWABLE_PIXMAP) {
        BoxRec TsrcBox;

        TsrcBox.x1 = srcx + pSrcDrawable->x;
        TsrcBox.y1 = srcy + pSrcDrawable->y;
        TsrcBox.x2 = TsrcBox.x1 + width;
        TsrcBox.y2 = TsrcBox.y1 + height;
        pSrcWin = (WindowPtr) pSrcDrawable;
        if (pGC->subWindowMode == IncludeInferiors) {
            prgnSrcClip = NotClippedByChildren(pSrcWin);
            if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) {
                RegionDestroy(prgnSrcClip);
                return NULL;
            }
        }
        else {
            if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN)
                return NULL;
            prgnSrcClip = &rgnSrcRec;
            RegionNull(prgnSrcClip);
            RegionCopy(prgnSrcClip, &pSrcWin->clipList);
        }
        RegionTranslate(prgnSrcClip, -pSrcDrawable->x, -pSrcDrawable->y);
    }
    else {
        BoxRec box;

        if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
            (srcBox.x2 <= pSrcDrawable->width) &&
            (srcBox.y2 <= pSrcDrawable->height))
            return NULL;

        box.x1 = 0;
        box.y1 = 0;
        box.x2 = pSrcDrawable->width;
        box.y2 = pSrcDrawable->height;
        prgnSrcClip = &rgnSrcRec;
        RegionInit(prgnSrcClip, &box, 1);
        pSrcWin = NULL;
    }

    if (pDstDrawable == pSrcDrawable) {
        prgnDstClip = prgnSrcClip;
    }
    else if (pDstDrawable->type != DRAWABLE_PIXMAP) {
        if (pGC->subWindowMode == IncludeInferiors) {
            prgnDstClip = NotClippedByChildren((WindowPtr) pDstDrawable);
        }
        else {
            prgnDstClip = &rgnDstRec;
            RegionNull(prgnDstClip);
            RegionCopy(prgnDstClip, &((WindowPtr) pDstDrawable)->clipList);
        }
        RegionTranslate(prgnDstClip, -pDstDrawable->x, -pDstDrawable->y);
    }
    else {
        BoxRec box;

        box.x1 = 0;
        box.y1 = 0;
        box.x2 = pDstDrawable->width;
        box.y2 = pDstDrawable->height;
        prgnDstClip = &rgnDstRec;
        RegionInit(prgnDstClip, &box, 1);
    }

    /* drawable-relative source region */
    RegionInit(&rgnExposed, &srcBox, 1);

    /* now get the hidden parts of the source box */
    RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip);

    /* move them over the destination */
    RegionTranslate(&rgnExposed, dstx - srcx, dsty - srcy);

    /* intersect with visible areas of dest */
    RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip);

    /* intersect with client clip region. */
    if (pGC->clientClipType == CT_REGION)
        RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip);

    /*
     * 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" :-)
     * for windows.
     */
    extents = pGC->graphicsExposures &&
        (RegionNumRects(&rgnExposed) > RECTLIMIT) &&
        (pDstDrawable->type != DRAWABLE_PIXMAP);
    if (pSrcWin) {
        RegionPtr region;

        if (!(region = wClipShape(pSrcWin)))
            region = wBoundingShape(pSrcWin);
        /*
         * If you try to CopyArea the extents of a shaped window, compacting the
         * exposed region will undo all our work!
         */
        if (extents && pSrcWin && region &&
            (RegionContainsRect(region, &srcBox) != rgnIN))
            extents = FALSE;
    }
    if (extents) {
        expBox = *RegionExtents(&rgnExposed);
        RegionReset(&rgnExposed, &expBox);
    }
    if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
        (((WindowPtr) pDstDrawable)->backgroundState != None)) {
        WindowPtr pWin = (WindowPtr) pDstDrawable;

        /* make the exposed area screen-relative */
        RegionTranslate(&rgnExposed, pDstDrawable->x, pDstDrawable->y);

        if (extents) {
            /* miPaintWindow doesn't clip, so we have to */
            RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList);
        }
        miPaintWindow((WindowPtr) pDstDrawable, &rgnExposed, PW_BACKGROUND);

        if (extents) {
            RegionReset(&rgnExposed, &expBox);
        }
        else
            RegionTranslate(&rgnExposed, -pDstDrawable->x, -pDstDrawable->y);
    }
    if (prgnDstClip == &rgnDstRec) {
        RegionUninit(prgnDstClip);
    }
    else if (prgnDstClip != prgnSrcClip) {
        RegionDestroy(prgnDstClip);
    }

    if (prgnSrcClip == &rgnSrcRec) {
        RegionUninit(prgnSrcClip);
    }
    else {
        RegionDestroy(prgnSrcClip);
    }

    if (pGC->graphicsExposures) {
        /* don't look */
        RegionPtr exposed = RegionCreate(NullBox, 0);

        *exposed = rgnExposed;
        return exposed;
    }
    else {
        RegionUninit(&rgnExposed);
        return NULL;
    }
}