Example #1
0
static void
update_screen(struct omap_screen_info *omaps)
{
    BoxPtr tmp;
    int i;

    if (region_is_null(omaps))
        return;

    if (!omaps->block_updates) {
        /* Remove the video region from our active area. */
        if (omaps->video_region &&
            REGION_NOTEMPTY(omaps->screen->pScreen, omaps->video_region) &&
            RECT_IN_REGION(omaps->screen->pScreen, omaps->video_region,
                           &omaps->dirty_area)) {
            REGION_INIT(omaps->screen->pScreen, omaps->tmp_region,
                        &omaps->dirty_area, 1);
            REGION_SUBTRACT(omaps->screen->pScreen, omaps->tmp_region,
                            omaps->tmp_region, omaps->video_region);
            tmp = REGION_RECTS(omaps->tmp_region);
            for (i = 0; i < REGION_NUM_RECTS(omaps->tmp_region); i++, tmp++)
                push_box(omaps, tmp);
            REGION_EMPTY(omaps->screen->pScreen, omaps->tmp_region);
        }
        else {
            push_box(omaps, &omaps->dirty_area);
        }

    }

    reset_damage(omaps);
}
Example #2
0
int
ProcXFixesCombineRegion (ClientPtr client)
{
    RegionPtr	pSource1, pSource2, pDestination;
    int		ret = Success;
    REQUEST (xXFixesCombineRegionReq);

    REQUEST_SIZE_MATCH (xXFixesCombineRegionReq);
    VERIFY_REGION(pSource1, stuff->source1, client, DixReadAccess);
    VERIFY_REGION(pSource2, stuff->source2, client, DixReadAccess);
    VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
    
    switch (stuff->xfixesReqType) {
    case X_XFixesUnionRegion:
	if (!REGION_UNION (0, pDestination, pSource1, pSource2))
	    ret = BadAlloc;
	break;
    case X_XFixesIntersectRegion:
	if (!REGION_INTERSECT (0, pDestination, pSource1, pSource2))
	    ret = BadAlloc;
	break;
    case X_XFixesSubtractRegion:
	if (!REGION_SUBTRACT (0, pDestination, pSource1, pSource2))
	    ret = BadAlloc;
	break;
    }
    
    if (ret == Success) 
	ret = client->noClientException;
    return ret;
}
Example #3
0
void
miSetShape(WindowPtr pWin)
{
    Bool	WasViewable = (Bool)(pWin->viewable);
    ScreenPtr 	pScreen = pWin->drawable.pScreen;
    Bool	anyMarked = FALSE;
    WindowPtr   pLayerWin;

    if (WasViewable)
    {
	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
						      &pLayerWin);
	if (pWin->valdata)
	{
	    if (HasBorder (pWin))
	    {
		RegionPtr	borderVisible;

		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
		REGION_SUBTRACT(pScreen, borderVisible,
				      &pWin->borderClip, &pWin->winSize);
		pWin->valdata->before.borderVisible = borderVisible;
	    }
	    pWin->valdata->before.resized = TRUE;
	}
    }

    SetWinSize (pWin);
    SetBorderSize (pWin);

    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);

    if (WasViewable)
    {
	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
						NULL);


	if (anyMarked)
	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
    }

    if (WasViewable)
    {
	if (anyMarked)
	    (*pScreen->HandleExposures)(pLayerWin->parent);
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
    CheckCursorConfinement(pWin);
}
Example #4
0
void
miChangeBorderWidth(WindowPtr pWin, unsigned int width)
{
    int oldwidth;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    Bool WasViewable = (Bool)(pWin->viewable);
    Bool HadBorder;
    WindowPtr  pLayerWin;

    oldwidth = wBorderWidth (pWin);
    if (oldwidth == width)
	return;
    HadBorder = HasBorder(pWin);
    pScreen = pWin->drawable.pScreen;
    if (WasViewable && width < oldwidth)
	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);

    pWin->borderWidth = width;
    SetBorderSize (pWin);

    if (WasViewable)
    {
	if (width > oldwidth)
	{
	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
							  &pLayerWin);
	    /*
	     * save the old border visible region to correctly compute
	     * borderExposed.
	     */
	    if (pWin->valdata && HadBorder)
	    {
		RegionPtr   borderVisible;
		borderVisible = REGION_CREATE(pScreen, NULL, 1);
		REGION_SUBTRACT(pScreen, borderVisible,
				      &pWin->borderClip, &pWin->winSize);
		pWin->valdata->before.borderVisible = borderVisible;
	    }
	}

	if (anyMarked)
	{
	    (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
	    (*pScreen->HandleExposures)(pLayerWin->parent);
	}
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
					  VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
}
Example #5
0
static int
miRecomputeExposures (
    WindowPtr	pWin,
    pointer		value) /* must conform to VisitWindowProcPtr */
{
    ScreenPtr	pScreen;
    RegionPtr	pValid = (RegionPtr)value;

    if (pWin->valdata)
    {
#ifdef COMPOSITE
	/*
	 * Redirected windows are not affected by parent window
	 * gravity manipulations, so don't recompute their
	 * exposed areas here.
	 */
	if (pWin->redirectDraw != RedirectDrawNone)
	    return WT_DONTWALKCHILDREN;
#endif
	pScreen = pWin->drawable.pScreen;
	/*
	 * compute exposed regions of this window
	 */
	REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
			&pWin->clipList, pValid);
	/*
	 * compute exposed regions of the border
	 */
	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
			     &pWin->borderClip, &pWin->winSize);
	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
			     &pWin->valdata->after.borderExposed, pValid);
	return WT_WALKCHILDREN;
    }
    return WT_NOMATCH;
}
Example #6
0
File: xf86fbman.c Project: aosm/X11
Bool
xf86InitFBManager(
    ScreenPtr pScreen,  
    BoxPtr FullBox
){
   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
   RegionRec ScreenRegion;
   RegionRec FullRegion;
   BoxRec ScreenBox;
   Bool ret;

   ScreenBox.x1 = 0;
   ScreenBox.y1 = 0;
   ScreenBox.x2 = pScrn->virtualX;
   ScreenBox.y2 = pScrn->virtualY;

   if((FullBox->x1 >  ScreenBox.x1) || (FullBox->y1 >  ScreenBox.y1) ||
      (FullBox->x2 <  ScreenBox.x2) || (FullBox->y2 <  ScreenBox.y2)) {
	return FALSE;   
   }

   if (FullBox->y2 < FullBox->y1) return FALSE;
   if (FullBox->x2 < FullBox->x2) return FALSE;

   REGION_INIT(pScreen, &ScreenRegion, &ScreenBox, 1); 
   REGION_INIT(pScreen, &FullRegion, FullBox, 1); 

   REGION_SUBTRACT(pScreen, &FullRegion, &FullRegion, &ScreenRegion);

   ret = xf86InitFBManagerRegion(pScreen, &FullRegion);

   REGION_UNINIT(pScreen, &ScreenRegion);
   REGION_UNINIT(pScreen, &FullRegion);
    
   return ret;
}
Example #7
0
static void
SegregateChildrenBpp(WindowPtr pWin, RegionPtr pReg, int subtract, int bpp, int other_bpp)
{
	WindowPtr pChild;

	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
		if (pChild->drawable.bitsPerPixel == bpp) {
			if (subtract) {
				REGION_SUBTRACT(pWin->drawable.pScreen, pReg,
						pReg, &pChild->borderClip);
			} else {
				REGION_UNION(pWin->drawable.pScreen, pReg,
					     pReg, &pChild->borderClip);
			}
			if (pChild->firstChild)
				SegregateChildrenBpp(pChild, pReg,
						     !subtract, other_bpp, bpp);
		} else {
			if (pChild->firstChild)
				SegregateChildrenBpp(pChild, pReg,
						     subtract, bpp, other_bpp);
		}
	}
}
Example #8
0
File: xf86fbman.c Project: aosm/X11
static Bool
localQueryLargestOffscreenArea(
    ScreenPtr pScreen,
    int *width, int *height,
    int granularity,
    int preferences,
    int severity
){
    FBManagerPtr offman;
    RegionPtr newRegion = NULL;
    BoxPtr pbox;
    int nbox;
    int x, w, h, area, oldArea;

    *width = *height = oldArea = 0;

    if(granularity <= 1) granularity = 0;

    if((preferences < 0) || (preferences > 3))
	return FALSE;	

    offman = pScreen->devPrivates[xf86FBScreenIndex].ptr;

    if(severity < 0) severity = 0;
    if(severity > 2) severity = 2;

    switch(severity) {
    case 2:
	if(offman->NumUsedAreas) {
	    FBLinkPtr pLink;
	    RegionRec tmpRegion;
	    newRegion = REGION_CREATE(pScreen, NULL, 1);
	    REGION_COPY(pScreen, newRegion, offman->InitialBoxes);
	    pLink = offman->UsedAreas;

	    while(pLink) {
		if(!pLink->area.RemoveAreaCallback) {
		    REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
		    REGION_SUBTRACT(pScreen, newRegion, newRegion, &tmpRegion);
		    REGION_UNINIT(pScreen, &tmpRegion);
		}
		pLink = pLink->next;
	    }

	    nbox = REGION_NUM_RECTS(newRegion);
	    pbox = REGION_RECTS(newRegion);
	    break;
	}
    case 1:
	if(offman->NumUsedAreas) {
	    FBLinkPtr pLink;
	    RegionRec tmpRegion;
	    newRegion = REGION_CREATE(pScreen, NULL, 1);
	    REGION_COPY(pScreen, newRegion, offman->FreeBoxes);
	    pLink = offman->UsedAreas;

	    while(pLink) {
		if(pLink->area.RemoveAreaCallback) {
		    REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
		    REGION_APPEND(pScreen, newRegion, &tmpRegion);
		    REGION_UNINIT(pScreen, &tmpRegion);
		}
		pLink = pLink->next;
	    }

	    nbox = REGION_NUM_RECTS(newRegion);
	    pbox = REGION_RECTS(newRegion);
	    break;
	}
    default:
	nbox = REGION_NUM_RECTS(offman->FreeBoxes);
	pbox = REGION_RECTS(offman->FreeBoxes);
	break;
    }

    while(nbox--) {
	x = pbox->x1;
	if(granularity) {
	   int tmp = x % granularity;
	   if(tmp) x += (granularity - tmp);
        }

	w = pbox->x2 - x;
	h = pbox->y2 - pbox->y1;
	area = w * h;

	if(w > 0) {
	    Bool gotIt = FALSE;
	    switch(preferences) {
	    case FAVOR_AREA_THEN_WIDTH:
		if((area > oldArea) || ((area == oldArea) && (w > *width))) 
		    gotIt = TRUE;
		break;
	    case FAVOR_AREA_THEN_HEIGHT:
		if((area > oldArea) || ((area == oldArea) && (h > *height)))
		    gotIt = TRUE;
		break;
	    case FAVOR_WIDTH_THEN_AREA:
		if((w > *width) || ((w == *width) && (area > oldArea)))
		    gotIt = TRUE;
		break;
	    case FAVOR_HEIGHT_THEN_AREA:
		if((h > *height) || ((h == *height) && (area > oldArea)))
		    gotIt = TRUE;
		break;
	    }
	    if(gotIt) {
		*width = w;
		*height = h;
		oldArea = area;
	    }
        }
	pbox++;
    }

    if(newRegion)
	REGION_DESTROY(pScreen, newRegion);

    return TRUE;
}
Example #9
0
File: xf86fbman.c Project: aosm/X11
static Bool
localResizeOffscreenArea(
   FBAreaPtr resize,
   int w, int h
){
   FBManagerPtr offman;
   ScreenPtr pScreen;
   BoxRec OrigArea;
   RegionRec FreedReg;
   FBAreaPtr area = NULL;
   FBLinkPtr pLink, newLink, pLinkPrev = NULL;

   pScreen = resize->pScreen;
   offman = pScreen->devPrivates[xf86FBScreenIndex].ptr;

   /* find this link */
   if(!(pLink = offman->UsedAreas))
	return FALSE;  
 
   while(&(pLink->area) != resize) {
	pLinkPrev = pLink;
	pLink = pLink->next;
	if(!pLink) return FALSE;
   }

   OrigArea.x1 = resize->box.x1;
   OrigArea.x2 = resize->box.x2;
   OrigArea.y1 = resize->box.y1;
   OrigArea.y2 = resize->box.y2;

   /* if it's smaller, this is easy */

   if((w <= (resize->box.x2 - resize->box.x1)) && 
      (h <= (resize->box.y2 - resize->box.y1))) {
	RegionRec NewReg;

	resize->box.x2 = resize->box.x1 + w;
	resize->box.y2 = resize->box.y1 + h;

        if((resize->box.y2 == OrigArea.y2) &&
	   (resize->box.x2 == OrigArea.x2))
		return TRUE;

	REGION_INIT(pScreen, &FreedReg, &OrigArea, 1); 
	REGION_INIT(pScreen, &NewReg, &(resize->box), 1); 
	REGION_SUBTRACT(pScreen, &FreedReg, &FreedReg, &NewReg);
	REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
	REGION_UNINIT(pScreen, &FreedReg); 
	REGION_UNINIT(pScreen, &NewReg); 

	SendCallFreeBoxCallbacks(offman);

	return TRUE;
   }


   /* otherwise we remove the old region */

   REGION_INIT(pScreen, &FreedReg, &OrigArea, 1); 
   REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
  
   /* remove the old link */
   if(pLinkPrev)
	pLinkPrev->next = pLink->next;
   else offman->UsedAreas = pLink->next;

   /* and try to add a new one */

   if((area = AllocateArea(offman, w, h, resize->granularity,
		resize->MoveAreaCallback, resize->RemoveAreaCallback,
		resize->devPrivate.ptr))) {

        /* copy data over to our link and replace the new with old */
	memcpy(resize, area, sizeof(FBArea));

        pLinkPrev = NULL;
 	newLink = offman->UsedAreas;

        while(&(newLink->area) != area) {
	    pLinkPrev = newLink;
	    newLink = newLink->next;
        }

	if(pLinkPrev)
	    pLinkPrev->next = newLink->next;
	else offman->UsedAreas = newLink->next;

        pLink->next = offman->UsedAreas;
        offman->UsedAreas = pLink;

	xfree(newLink);

	/* AllocateArea added one but we really only exchanged one */
	offman->NumUsedAreas--;  
   } else {
      /* reinstate the old region */
      REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
      REGION_UNINIT(pScreen, &FreedReg); 

      pLink->next = offman->UsedAreas;
      offman->UsedAreas = pLink;
      return FALSE;
   }


   REGION_UNINIT(pScreen, &FreedReg); 

   SendCallFreeBoxCallbacks(offman);

   return TRUE;
}
Example #10
0
File: xf86fbman.c Project: aosm/X11
static FBAreaPtr
AllocateArea(
   FBManagerPtr offman,
   int w, int h,
   int granularity,
   MoveAreaCallbackProcPtr moveCB,
   RemoveAreaCallbackProcPtr removeCB,
   pointer privData
){
   ScreenPtr pScreen = offman->pScreen;
   FBLinkPtr link = NULL;
   FBAreaPtr area = NULL;
   RegionRec NewReg;
   int i, x = 0, num;
   BoxPtr boxp;

   if(granularity <= 1) granularity = 0;

   boxp = REGION_RECTS(offman->FreeBoxes);
   num = REGION_NUM_RECTS(offman->FreeBoxes);

   /* look through the free boxes */
   for(i = 0; i < num; i++, boxp++) {
	x = boxp->x1;
	if(granularity) {
	    int tmp = x % granularity;
	    if(tmp) x += (granularity - tmp);
	}

	if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w))
	   continue;

	link = xalloc(sizeof(FBLink));
	if(!link) return NULL;

        area = &(link->area);
        link->next = offman->UsedAreas;
        offman->UsedAreas = link;
        offman->NumUsedAreas++;
	break;
   }

   /* try to boot a removeable one out if we are not expendable ourselves */
   if(!area && !removeCB) {
	link = offman->UsedAreas;

	while(link) {
	   if(!link->area.RemoveAreaCallback) {
		link = link->next;
		continue;
	   }

	   boxp = &(link->area.box);
	   x = boxp->x1;
 	   if(granularity) {
		int tmp = x % granularity;
		if(tmp) x += (granularity - tmp);
	   }

	   if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w)) {
		link = link->next;
		continue;
	   }

	   /* bye, bye */
	   (*link->area.RemoveAreaCallback)(&link->area);
	   REGION_INIT(pScreen, &NewReg, &(link->area.box), 1); 
	   REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
	   REGION_UNINIT(pScreen, &NewReg); 

           area = &(link->area);
	   break;
	}
   }

   if(area) {
	area->pScreen = pScreen;
	area->granularity = granularity;
	area->box.x1 = x;
	area->box.x2 = x + w;
	area->box.y1 = boxp->y1;
	area->box.y2 = boxp->y1 + h;
	area->MoveAreaCallback = moveCB;
	area->RemoveAreaCallback = removeCB;
	area->devPrivate.ptr = privData;

        REGION_INIT(pScreen, &NewReg, &(area->box), 1);
	REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
	REGION_UNINIT(pScreen, &NewReg);
   }

   return area;
}
Example #11
0
File: xf86fbman.c Project: aosm/X11
Bool
xf86InitFBManagerArea(
    ScreenPtr pScreen,
    int PixelArea,
    int Verbosity
)
{
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    xRectangle Rect[3];
    RegionPtr pRegion, pScreenRegion;
    int nRect;
    Bool ret = FALSE;

    if (PixelArea < (pScrn->displayWidth * pScrn->virtualY))
	return FALSE;

    Rect[0].x = Rect[0].y = 0;
    Rect[0].width = pScrn->displayWidth;
    Rect[0].height = PixelArea / pScrn->displayWidth;
    nRect = 1;

    /* Add a possible partial scanline */
    if ((Rect[1].height = Rect[1].width = PixelArea % pScrn->displayWidth)) {
	Rect[1].x = 0;
	Rect[1].y = Rect[0].height;
	Rect[1].height = 1;
	nRect++;
    }

    /* Factor out virtual resolution */
    pRegion = RECTS_TO_REGION(pScreen, nRect, Rect, 0);
    if (pRegion) {
	if (!REGION_NAR(pRegion)) {
	    Rect[2].x = Rect[2].y = 0;
	    Rect[2].width = pScrn->virtualX;
	    Rect[2].height = pScrn->virtualY;

	    pScreenRegion = RECTS_TO_REGION(pScreen, 1, &Rect[2], 0);
	    if (pScreenRegion) {
		if (!REGION_NAR(pScreenRegion)) {
		    REGION_SUBTRACT(pScreen, pRegion, pRegion, pScreenRegion);

		    ret = xf86InitFBManagerRegion(pScreen, pRegion);

		    if (ret && xf86GetVerbosity() >= Verbosity) {
			int scrnIndex = pScrn->scrnIndex;

			xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
			    "Largest offscreen areas (with overlaps):\n");

			if (Rect[2].width < Rect[0].width) {
			    xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
				"\t%d x %d rectangle at %d,0\n",
				Rect[0].width - Rect[2].width,
				Rect[0].height,
				Rect[2].width);
			}
			if (Rect[2].width < Rect[1].width) {
			    xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
				"\t%d x %d rectangle at %d,0\n",
				Rect[1].width - Rect[2].width,
				Rect[0].height + Rect[1].height,
				Rect[2].width);
			}
			if (Rect[2].height < Rect[0].height) {
			    xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
				"\t%d x %d rectangle at 0,%d\n",
				Rect[0].width,
				Rect[0].height - Rect[2].height,
				Rect[2].height);
			}
			if (Rect[1].height) {
			    xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
				"\t%d x %d rectangle at 0,%d\n",
				Rect[1].width,
				Rect[0].height - Rect[2].height +
				    Rect[1].height,
				Rect[2].height);
			}
		    }
		}

		REGION_DESTROY(pScreen, pScreenRegion);
	    }
	}

	REGION_DESTROY(pScreen, pRegion);
    }

    return ret;
}
/* XaceCensorImage
 *
 * Called after pScreen->GetImage to prevent pieces or trusted windows from
 * being returned in image data from an untrusted window.
 *
 * Arguments:
 *	client is the client doing the GetImage.
 *      pVisibleRegion is the visible region of the window.
 *	widthBytesLine is the width in bytes of one horizontal line in pBuf.
 *	pDraw is the source window.
 *	x, y, w, h is the rectangle of image data from pDraw in pBuf.
 *	format is the format of the image data in pBuf: ZPixmap or XYPixmap.
 *	pBuf is the image data.
 *
 * Returns: nothing.
 *
 * Side Effects:
 *	Any part of the rectangle (x, y, w, h) that is outside the visible
 *	region of the window will be destroyed (overwritten) in pBuf.
 */
void
XaceCensorImage(
	ClientPtr client,
	RegionPtr pVisibleRegion,
	long widthBytesLine,
	DrawablePtr pDraw,
	int x, int y, int w, int h,
	unsigned int format,
	char *pBuf)
{
    ScreenPtr pScreen;
    RegionRec imageRegion;  /* region representing x,y,w,h */
    RegionRec censorRegion; /* region to obliterate */
    BoxRec imageBox;
    int nRects;

    pScreen = pDraw->pScreen;

    imageBox.x1 = x;
    imageBox.y1 = y;
    imageBox.x2 = x + w;
    imageBox.y2 = y + h;
    REGION_INIT(pScreen, &imageRegion, &imageBox, 1);
    REGION_NULL(pScreen, &censorRegion);

    /* censorRegion = imageRegion - visibleRegion */
    REGION_SUBTRACT(pScreen, &censorRegion, &imageRegion, pVisibleRegion);
    nRects = REGION_NUM_RECTS(&censorRegion);
    if (nRects > 0)
    { /* we have something to censor */
	GCPtr pScratchGC = NULL;
	PixmapPtr pPix = NULL;
	xRectangle *pRects = NULL;
	Bool failed = FALSE;
	int depth = 1;
	int bitsPerPixel = 1;
	int i;
	BoxPtr pBox;

	/* convert region to list-of-rectangles for PolyFillRect */

	pRects = xalloc(nRects * sizeof(xRectangle));
	if (!pRects)
	{
	    failed = TRUE;
	    goto failSafe;
	}
	for (pBox = REGION_RECTS(&censorRegion), i = 0;
	     i < nRects;
	     i++, pBox++)
	{
	    pRects[i].x = pBox->x1;
	    pRects[i].y = pBox->y1 - imageBox.y1;
	    pRects[i].width  = pBox->x2 - pBox->x1;
	    pRects[i].height = pBox->y2 - pBox->y1;
	}

	/* use pBuf as a fake pixmap */

	if (format == ZPixmap)
	{
	    depth = pDraw->depth;
	    bitsPerPixel = pDraw->bitsPerPixel;
	}

	pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
		    depth, bitsPerPixel,
		    widthBytesLine, (pointer)pBuf);
	if (!pPix)
	{
	    failed = TRUE;
	    goto failSafe;
	}

	pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen);
	if (!pScratchGC)
	{
	    failed = TRUE;
	    goto failSafe;
	}

	ValidateGC(&pPix->drawable, pScratchGC);
	(* pScratchGC->ops->PolyFillRect)(&pPix->drawable,
			    pScratchGC, nRects, pRects);

    failSafe:
	if (failed)
	{
	    /* Censoring was not completed above.  To be safe, wipe out
	     * all the image data so that nothing trusted gets out.
	     */
	    bzero(pBuf, (int)(widthBytesLine * h));
	}
	if (pRects)     xfree(pRects);
	if (pScratchGC) FreeScratchGC(pScratchGC);
	if (pPix)       FreeScratchPixmapHeader(pPix);
    }
    REGION_UNINIT(pScreen, &imageRegion);
    REGION_UNINIT(pScreen, &censorRegion);
} /* XaceCensorImage */
Example #13
0
static void
xf86SetRootClip (ScreenPtr pScreen, Bool enable)
{
#if XORG < 19
    WindowPtr	pWin = WindowTable[pScreen->myNum];
#else
    WindowPtr	pWin = pScreen->root;
#endif
    WindowPtr	pChild;
    Bool	WasViewable = (Bool)(pWin->viewable);
    Bool	anyMarked = FALSE;
#if XORG < 110
    RegionPtr	pOldClip = NULL, bsExposed;
#ifdef DO_SAVE_UNDERS
    Bool	dosave = FALSE;
#endif
#endif
    WindowPtr   pLayerWin;
    BoxRec	box;

    if (WasViewable)
    {
	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	{
	    (void) (*pScreen->MarkOverlappedWindows)(pChild,
						     pChild,
						     &pLayerWin);
	}
	(*pScreen->MarkWindow) (pWin);
	anyMarked = TRUE;
	if (pWin->valdata)
	{
	    if (HasBorder (pWin))
	    {
		RegionPtr	borderVisible;

		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
		REGION_SUBTRACT(pScreen, borderVisible,
				&pWin->borderClip, &pWin->winSize);
		pWin->valdata->before.borderVisible = borderVisible;
	    }
	    pWin->valdata->before.resized = TRUE;
	}
    }
    
    /*
     * Use REGION_BREAK to avoid optimizations in ValidateTree
     * that assume the root borderClip can't change well, normally
     * it doesn't...)
     */
    if (enable)
    {
	box.x1 = 0;
	box.y1 = 0;
	box.x2 = pScreen->width;
	box.y2 = pScreen->height;
	REGION_INIT (pScreen, &pWin->winSize, &box, 1);
	REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
	if (WasViewable)
	    REGION_RESET(pScreen, &pWin->borderClip, &box);
	pWin->drawable.width = pScreen->width;
	pWin->drawable.height = pScreen->height;
        REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
    }
    else
    {
	REGION_EMPTY(pScreen, &pWin->borderClip);
	REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
    }
    
    ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
    
    if (WasViewable)
    {
#if XORG < 110
	if (pWin->backStorage)
	{
	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
	}
#endif

	if (pWin->firstChild)
	{
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
							   pWin->firstChild,
							   (WindowPtr *)NULL);
	}
	else
	{
	    (*pScreen->MarkWindow) (pWin);
	    anyMarked = TRUE;
	}

#if XORG < 110 && defined(DO_SAVE_UNDERS)
	if (DO_SAVE_UNDERS(pWin))
	{
	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
	}
#endif /* DO_SAVE_UNDERS */

	if (anyMarked)
	    (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
    }

#if XORG < 110
    if (pWin->backStorage &&
	((pWin->backingStore == Always) || WasViewable))
    {
	if (!WasViewable)
	    pOldClip = &pWin->clipList; /* a convenient empty region */
	bsExposed = (*pScreen->TranslateBackingStore)
			     (pWin, 0, 0, pOldClip,
			      pWin->drawable.x, pWin->drawable.y);
	if (WasViewable)
	    REGION_DESTROY(pScreen, pOldClip);
	if (bsExposed)
	{
	    RegionPtr	valExposed = NullRegion;
    
	    if (pWin->valdata)
		valExposed = &pWin->valdata->after.exposed;
	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
	    if (valExposed)
		REGION_EMPTY(pScreen, valExposed);
	    REGION_DESTROY(pScreen, bsExposed);
	}
    }
#endif
    if (WasViewable)
    {
	if (anyMarked)
	    (*pScreen->HandleExposures)(pWin);

#if XORG < 110 && defined(DO_SAVE_UNDERS)
	if (dosave)
	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
#endif /* DO_SAVE_UNDERS */
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
    FlushAllOutput ();
}
Example #14
0
/*
 *-----------------------------------------------------------------------
 * RootlessComputeClips --
 *	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
RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, 
		      RegionPtr universe, VTKind kind, RegionPtr exposed)
{
    int			dx,
			dy;
    RegionRec		childUniverse;
    register WindowPtr	pChild;
    int     	  	oldVis, newVis;
    BoxRec		borderSize;
    RegionRec		childUnion;
    Bool		overlap;
    RegionPtr		borderVisible;
    Bool		resized;
    /*
     * 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;

    oldVis = pParent->visibility;
    switch (RECT_IN_REGION( pScreen, universe, &borderSize)) 
    {
    case rgnIN:
	    newVis = VisibilityUnobscured;
	    break;
	case rgnPART:
	    newVis = VisibilityPartiallyObscured;
	    {
		RegionPtr   pBounding;

		if ((pBounding = wBoundingShape (pParent)))
		{
		    switch (RootlessShapedWindowIn (pScreen, 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)
		    {
			REGION_TRANSLATE( pScreen, &pChild->borderClip,
						      dx, dy);
			REGION_TRANSLATE( pScreen, &pChild->clipList,
						      dx, dy);
			pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
			if (pScreen->ClipNotify)
			    (* pScreen->ClipNotify) (pChild, dx, dy);

		    }
		    if (pChild->valdata)
		    {
			REGION_NULL(pScreen,
				    &pChild->valdata->after.borderExposed);
			if (HasParentRelativeBorder(pChild))
			  {
			    REGION_SUBTRACT(pScreen,
					 &pChild->valdata->after.borderExposed,
					 &pChild->borderClip,
					 &pChild->winSize);
			}
			REGION_NULL(pScreen, &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.
	     */
	    REGION_TRANSLATE( pScreen, &pParent->borderClip, dx, dy);
	    REGION_TRANSLATE( pScreen, &pParent->clipList, dx, dy);
    	} 
	break;
    case VTBroken:
	REGION_EMPTY (pScreen, &pParent->borderClip);
	REGION_EMPTY (pScreen, &pParent->clipList);
	break;
    }

    borderVisible = pParent->valdata->before.borderVisible;
    resized = pParent->valdata->before.resized;
    REGION_NULL(pScreen, &pParent->valdata->after.borderExposed);
    REGION_NULL(pScreen, &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
	     */
	    REGION_SUBTRACT( pScreen, exposed, universe, borderVisible);
	    REGION_DESTROY( pScreen, borderVisible);
    	}
    	else
    	{
	    REGION_SUBTRACT( pScreen, exposed, universe, &pParent->borderClip);
    	}
	if (HasParentRelativeBorder(pParent) && (dx || dy)) {
	    REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
				  universe,
				  &pParent->winSize);
	} else {
	    REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
			       exposed, &pParent->winSize);
	}

    	REGION_COPY( pScreen, &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.
     	 */
    
    	REGION_INTERSECT( pScreen, universe, universe, &pParent->winSize);
    }
    else
    	REGION_COPY( pScreen, &pParent->borderClip, universe);
    
    if ((pChild = pParent->firstChild) && pParent->mapped)
    {
	REGION_NULL(pScreen, &childUniverse);
	REGION_NULL(pScreen, &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)
		    REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
	    }
	}
	else
	{
	    for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
	    {
		if (pChild->viewable)
		    REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
	    }
	}
	REGION_VALIDATE( pScreen, &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.
		     */
		    REGION_INTERSECT( pScreen, &childUniverse,
					    universe,
					    &pChild->borderSize);
		    RootlessComputeClips (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)
		    REGION_SUBTRACT( pScreen, universe, universe,
					  &pChild->borderSize);
	    }
	}
	if (!overlap)
	    REGION_SUBTRACT( pScreen, universe, universe, &childUnion);
	REGION_UNINIT( pScreen, &childUnion);
	REGION_UNINIT( pScreen, &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)
    {
	REGION_COPY( pScreen, &pParent->valdata->after.exposed, universe);
    }
    else if (newVis != VisibilityFullyObscured &&
	     newVis != VisibilityNotViewable)
    {
    	REGION_SUBTRACT( pScreen, &pParent->valdata->after.exposed,
			       universe, &pParent->clipList);
    }

    /*
     * One last thing: backing storage. We have to try to save what parts of
     * the window are about to be obscured. We can just subtract the universe
     * from the old clipList and get the areas that were in the old but aren't
     * in the new and, hence, are about to be obscured.
     */
    if (pParent->backStorage && !resized)
    {
	REGION_SUBTRACT( pScreen, exposed, &pParent->clipList, universe);
	(* pScreen->SaveDoomedAreas)(pParent, exposed, dx, dy);
    }
    
    /* HACK ALERT - copying contents of regions, instead of regions */
    {
	RegionRec   tmp;

	tmp = pParent->clipList;
	pParent->clipList = *universe;
	*universe = tmp;
    }

#ifdef NOTDEF
    REGION_COPY( pScreen, &pParent->clipList, universe);
#endif

    pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;

    if (pScreen->ClipNotify)
	(* pScreen->ClipNotify) (pParent, dx, dy);
}
Example #15
0
void
miSlideAndSizeWindow(WindowPtr pWin,
                     int x, int y,
                     unsigned int w, unsigned int h,
                     WindowPtr pSib)
{
    WindowPtr pParent;
    Bool WasViewable = (Bool)(pWin->viewable);
    unsigned short width = pWin->drawable.width,
		   height = pWin->drawable.height;
    short oldx = pWin->drawable.x,
	  oldy = pWin->drawable.y;
    int bw = wBorderWidth (pWin);
    short dw, dh;
    DDXPointRec oldpt;
    RegionPtr oldRegion = NULL;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    WindowPtr pFirstChange;
    WindowPtr pChild;
    RegionPtr	gravitate[StaticGravity + 1];
    unsigned g;
    int		nx, ny;		/* destination x,y */
    int		newx, newy;	/* new inner window position */
    RegionPtr	pRegion = NULL;
    RegionPtr	destClip;	/* portions of destination already written */
    RegionPtr	oldWinClip = NULL;	/* old clip list for window */
    RegionPtr	borderVisible = NullRegion; /* visible area of the border */
    Bool	shrunk = FALSE; /* shrunk in an inner dimension */
    Bool	moved = FALSE;	/* window position changed */
    WindowPtr  pLayerWin;

    /* if this is a root window, can't be resized */
    if (!(pParent = pWin->parent))
	return ;

    pScreen = pWin->drawable.pScreen;
    newx = pParent->drawable.x + x + bw;
    newy = pParent->drawable.y + y + bw;
    if (WasViewable)
    {
	anyMarked = FALSE;
	/*
	 * save the visible region of the window
	 */
	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
	REGION_COPY(pScreen, oldRegion, &pWin->winSize);

	/*
	 * categorize child windows into regions to be moved
	 */
	for (g = 0; g <= StaticGravity; g++)
	    gravitate[g] = (RegionPtr) NULL;
	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	{
	    g = pChild->winGravity;
	    if (g != UnmapGravity)
	    {
		if (!gravitate[g])
		    gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
		REGION_UNION(pScreen, gravitate[g],
				   gravitate[g], &pChild->borderClip);
	    }
	    else
	    {
		UnmapWindow(pChild, TRUE);
		anyMarked = TRUE;
	    }
	}
	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 
						       &pLayerWin);

	oldWinClip = NULL;
	if (pWin->bitGravity != ForgetGravity)
	{
	    oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
	    REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
	}
	/*
	 * if the window is changing size, borderExposed
	 * can't be computed correctly without some help.
	 */
	if (pWin->drawable.height > h || pWin->drawable.width > w)
	    shrunk = TRUE;

	if (newx != oldx || newy != oldy)
	    moved = TRUE;

	if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
	    HasBorder (pWin))
	{
	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
	    /* for tiled borders, we punt and draw the whole thing */
	    if (pWin->borderIsPixel || !moved)
	    {
		if (shrunk || moved)
		    REGION_SUBTRACT(pScreen, borderVisible,
					  &pWin->borderClip,
					  &pWin->winSize);
		else
		    REGION_COPY(pScreen, borderVisible,
					    &pWin->borderClip);
	    }
	}
    }
    pWin->origin.x = x + bw;
    pWin->origin.y = y + bw;
    pWin->drawable.height = h;
    pWin->drawable.width = w;

    x = pWin->drawable.x = newx;
    y = pWin->drawable.y = newy;

    SetWinSize (pWin);
    SetBorderSize (pWin);

    dw = (int)w - (int)width;
    dh = (int)h - (int)height;
    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);

    /* let the hardware adjust background and border pixmaps, if any */
    (*pScreen->PositionWindow)(pWin, x, y);

    pFirstChange = MoveWindowInStack(pWin, pSib);

    if (WasViewable)
    {
	pRegion = REGION_CREATE(pScreen, NullBox, 1);

	if (pLayerWin == pWin)
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
						NULL);
	else
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
						NULL);

	if (pWin->valdata)
	{
	    pWin->valdata->before.resized = TRUE;
	    pWin->valdata->before.borderVisible = borderVisible;
	}


	if (anyMarked)
	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
	/*
	 * the entire window is trashed unless bitGravity
	 * recovers portions of it
	 */
	REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
    }

    GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);

    if (WasViewable)
    {
	/* avoid the border */
	if (HasBorder (pWin))
	{
	    int	offx, offy, dx, dy;

	    /* kruft to avoid double translates for each gravity */
	    offx = 0;
	    offy = 0;
	    for (g = 0; g <= StaticGravity; g++)
	    {
		if (!gravitate[g])
		    continue;

		/* align winSize to gravitate[g].
		 * winSize is in new coordinates,
		 * gravitate[g] is still in old coordinates */
		GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
		
		dx = (oldx - nx) - offx;
		dy = (oldy - ny) - offy;
		if (dx || dy)
		{
		    REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
		    offx += dx;
		    offy += dy;
		}
		REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
				 &pWin->winSize);
	    }
	    /* get winSize back where it belongs */
	    if (offx || offy)
		REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
	}
	/*
	 * add screen bits to the appropriate bucket
	 */

	if (oldWinClip)
	{
	    /*
	     * clip to new clipList
	     */
	    REGION_COPY(pScreen, pRegion, oldWinClip);
	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
	    REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
	    /*
	     * don't step on any gravity bits which will be copied after this
	     * region.	Note -- this assumes that the regions will be copied
	     * in gravity order.
	     */
	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
	    {
		if (gravitate[g])
		    REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
					gravitate[g]);
	    }
	    REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
	    g = pWin->bitGravity;
	    if (!gravitate[g])
		gravitate[g] = oldWinClip;
	    else
	    {
		REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
		REGION_DESTROY(pScreen, oldWinClip);
	    }
	}

	/*
	 * move the bits on the screen
	 */

	destClip = NULL;

	for (g = 0; g <= StaticGravity; g++)
	{
	    if (!gravitate[g])
		continue;

	    GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);

	    oldpt.x = oldx + (x - nx);
	    oldpt.y = oldy + (y - ny);

	    /* Note that gravitate[g] is *translated* by CopyWindow */

	    /* only copy the remaining useful bits */

	    REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);

	    /* clip to not overwrite already copied areas */

	    if (destClip) {
		REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
		REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
		REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
	    }

	    /* and move those bits */

	    if (oldpt.x != x || oldpt.y != y
#ifdef COMPOSITE
		|| pWin->redirectDraw
#endif
		)
	    {
		(*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
	    }

	    /* remove any overwritten bits from the remaining useful bits */

	    REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);

	    /*
	     * recompute exposed regions of child windows
	     */
	
	    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	    {
		if (pChild->winGravity != g)
		    continue;
		REGION_INTERSECT(pScreen, pRegion,
				       &pChild->borderClip, gravitate[g]);
		TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
	    }

	    /*
	     * remove the successfully copied regions of the
	     * window from its exposed region
	     */

	    if (g == pWin->bitGravity)
		REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
				     &pWin->valdata->after.exposed, gravitate[g]);
	    if (!destClip)
		destClip = gravitate[g];
	    else
	    {
		REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
		REGION_DESTROY(pScreen, gravitate[g]);
	    }
	}

	REGION_DESTROY(pScreen, oldRegion);
	REGION_DESTROY(pScreen, pRegion);
	if (destClip)
	    REGION_DESTROY(pScreen, destClip);
	if (anyMarked)
	    (*pScreen->HandleExposures)(pLayerWin->parent);
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
					  VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
}
Example #16
0
/* Entry point for hook functions.  Called by Xserver.
 */
int XaceHook(int hook, ...)
{
    pointer calldata;	/* data passed to callback */
    int *prv = NULL;	/* points to return value from callback */
    va_list ap;		/* argument list */
    va_start(ap, hook);

    /* Marshal arguments for passing to callback.
     * Each callback has its own case, which sets up a structure to hold
     * the arguments and integer return parameter, or in some cases just
     * sets calldata directly to a single argument (with no return result)
     */
    switch (hook)
    {
	case XACE_RESOURCE_ACCESS: {
	    XaceResourceAccessRec rec = {
		va_arg(ap, ClientPtr),
		va_arg(ap, XID),
		va_arg(ap, RESTYPE),
		va_arg(ap, pointer),
		va_arg(ap, RESTYPE),
		va_arg(ap, pointer),
		va_arg(ap, Mask),
		Success /* default allow */
	    };
	    calldata = &rec;
	    prv = &rec.status;
	    break;
	}
	case XACE_DEVICE_ACCESS: {
	    XaceDeviceAccessRec rec = {
		va_arg(ap, ClientPtr),
		va_arg(ap, DeviceIntPtr),
		va_arg(ap, Mask),
		Success /* default allow */
	    };
	    calldata = &rec;
	    prv = &rec.status;
	    break;
	}
	case XACE_SEND_ACCESS: {
	    XaceSendAccessRec rec = {
		va_arg(ap, ClientPtr),
		va_arg(ap, DeviceIntPtr),
		va_arg(ap, WindowPtr),
		va_arg(ap, xEventPtr),
		va_arg(ap, int),
		Success /* default allow */
	    };
	    calldata = &rec;
	    prv = &rec.status;
	    break;
	}
	case XACE_RECEIVE_ACCESS: {
	    XaceReceiveAccessRec rec = {
		va_arg(ap, ClientPtr),
		va_arg(ap, WindowPtr),
		va_arg(ap, xEventPtr),
		va_arg(ap, int),
		Success /* default allow */
	    };
	    calldata = &rec;
	    prv = &rec.status;
	    break;
	}
	case XACE_CLIENT_ACCESS: {
	    XaceClientAccessRec rec = {
		va_arg(ap, ClientPtr),
		va_arg(ap, ClientPtr),
		va_arg(ap, Mask),
		Success /* default allow */
	    };
	    calldata = &rec;
	    prv = &rec.status;
	    break;
	}
	case XACE_EXT_ACCESS: {
	    XaceExtAccessRec rec = {
		va_arg(ap, ClientPtr),
		va_arg(ap, ExtensionEntry*),
		DixGetAttrAccess,
		Success /* default allow */
	    };
	    calldata = &rec;
	    prv = &rec.status;
	    break;
	}
	case XACE_SERVER_ACCESS: {
	    XaceServerAccessRec rec = {
		va_arg(ap, ClientPtr),
		va_arg(ap, Mask),
		Success /* default allow */
	    };
	    calldata = &rec;
	    prv = &rec.status;
	    break;
	}
	case XACE_SCREEN_ACCESS:
	case XACE_SCREENSAVER_ACCESS: {
	    XaceScreenAccessRec rec = {
		va_arg(ap, ClientPtr),
		va_arg(ap, ScreenPtr),
		va_arg(ap, Mask),
		Success /* default allow */
	    };
	    calldata = &rec;
	    prv = &rec.status;
	    break;
	}
	case XACE_AUTH_AVAIL: {
	    XaceAuthAvailRec rec = {
		va_arg(ap, ClientPtr),
		va_arg(ap, XID)
	    };
	    calldata = &rec;
	    break;
	}
	case XACE_KEY_AVAIL: {
	    XaceKeyAvailRec rec = {
		va_arg(ap, xEventPtr),
		va_arg(ap, DeviceIntPtr),
		va_arg(ap, int)
	    };
	    calldata = &rec;
	    break;
	}
	default: {
	    va_end(ap);
	    return 0;	/* unimplemented hook number */
	}
    }
    va_end(ap);
 
    /* call callbacks and return result, if any. */
    CallCallbacks(&XaceHooks[hook], calldata);
    return prv ? *prv : Success;
}

/* XaceCensorImage
 *
 * Called after pScreen->GetImage to prevent pieces or trusted windows from
 * being returned in image data from an untrusted window.
 *
 * Arguments:
 *	client is the client doing the GetImage.
 *      pVisibleRegion is the visible region of the window.
 *	widthBytesLine is the width in bytes of one horizontal line in pBuf.
 *	pDraw is the source window.
 *	x, y, w, h is the rectangle of image data from pDraw in pBuf.
 *	format is the format of the image data in pBuf: ZPixmap or XYPixmap.
 *	pBuf is the image data.
 *
 * Returns: nothing.
 *
 * Side Effects:
 *	Any part of the rectangle (x, y, w, h) that is outside the visible
 *	region of the window will be destroyed (overwritten) in pBuf.
 */
void
XaceCensorImage(client, pVisibleRegion, widthBytesLine, pDraw, x, y, w, h,
		format, pBuf)
    ClientPtr client;
    RegionPtr pVisibleRegion;
    long widthBytesLine;
    DrawablePtr pDraw;
    int x, y, w, h;
    unsigned int format;
    char * pBuf;
{
    ScreenPtr pScreen;
    RegionRec imageRegion;  /* region representing x,y,w,h */
    RegionRec censorRegion; /* region to obliterate */
    BoxRec imageBox;
    int nRects;

    pScreen = pDraw->pScreen;

    imageBox.x1 = x;
    imageBox.y1 = y;
    imageBox.x2 = x + w;
    imageBox.y2 = y + h;
    REGION_INIT(pScreen, &imageRegion, &imageBox, 1);
    REGION_NULL(pScreen, &censorRegion);

    /* censorRegion = imageRegion - visibleRegion */
    REGION_SUBTRACT(pScreen, &censorRegion, &imageRegion, pVisibleRegion);
    nRects = REGION_NUM_RECTS(&censorRegion);
    if (nRects > 0)
    { /* we have something to censor */
	GCPtr pScratchGC = NULL;
	PixmapPtr pPix = NULL;
	xRectangle *pRects = NULL;
	Bool failed = FALSE;
	int depth = 1;
	int bitsPerPixel = 1;
	int i;
	BoxPtr pBox;

	/* convert region to list-of-rectangles for PolyFillRect */

	pRects = (xRectangle *)xalloc(nRects * sizeof(xRectangle));
	if (!pRects)
	{
	    failed = TRUE;
	    goto failSafe;
	}
	for (pBox = REGION_RECTS(&censorRegion), i = 0;
	     i < nRects;
	     i++, pBox++)
	{
	    pRects[i].x = pBox->x1;
	    pRects[i].y = pBox->y1 - imageBox.y1;
	    pRects[i].width  = pBox->x2 - pBox->x1;
	    pRects[i].height = pBox->y2 - pBox->y1;
	}

	/* use pBuf as a fake pixmap */

	if (format == ZPixmap)
	{
	    depth = pDraw->depth;
	    bitsPerPixel = pDraw->bitsPerPixel;
	}

	pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
		    depth, bitsPerPixel,
		    widthBytesLine, (pointer)pBuf);
	if (!pPix)
	{
	    failed = TRUE;
	    goto failSafe;
	}

	pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen);
	if (!pScratchGC)
	{
	    failed = TRUE;
	    goto failSafe;
	}

	ValidateGC(&pPix->drawable, pScratchGC);
	(* pScratchGC->ops->PolyFillRect)(&pPix->drawable,
			    pScratchGC, nRects, pRects);

    failSafe:
	if (failed)
	{
	    /* Censoring was not completed above.  To be safe, wipe out
	     * all the image data so that nothing trusted gets out.
	     */
	    bzero(pBuf, (int)(widthBytesLine * h));
	}
	if (pRects)     xfree(pRects);
	if (pScratchGC) FreeScratchGC(pScratchGC);
	if (pPix)       FreeScratchPixmapHeader(pPix);
    }
    REGION_UNINIT(pScreen, &imageRegion);
    REGION_UNINIT(pScreen, &censorRegion);
} /* XaceCensorImage */
Example #17
0
void
KdSetRootClip (ScreenPtr pScreen, BOOL enable)
{
#ifndef FB_OLD_SCREEN
    WindowPtr	pWin = WindowTable[pScreen->myNum];
    WindowPtr	pChild;
    Bool	WasViewable;
    Bool	anyMarked = FALSE;
    RegionPtr	pOldClip = 0, bsExposed;
#ifdef DO_SAVE_UNDERS
    Bool	dosave = FALSE;
#endif
    WindowPtr   pLayerWin;
    BoxRec	box;

    if (!pWin)
	return;
    WasViewable = (Bool)(pWin->viewable);
    if (WasViewable)
    {
	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	{
	    (void) (*pScreen->MarkOverlappedWindows)(pChild,
						     pChild,
						     &pLayerWin);
	}
	(*pScreen->MarkWindow) (pWin);
	anyMarked = TRUE;
	if (pWin->valdata)
	{
	    if (HasBorder (pWin))
	    {
		RegionPtr	borderVisible;

		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
		REGION_SUBTRACT(pScreen, borderVisible,
				&pWin->borderClip, &pWin->winSize);
		pWin->valdata->before.borderVisible = borderVisible;
	    }
	    pWin->valdata->before.resized = TRUE;
	}
    }

    if (enable)
    {
	box.x1 = 0;
	box.y1 = 0;
	box.x2 = pScreen->width;
	box.y2 = pScreen->height;
	pWin->drawable.width = pScreen->width;
	pWin->drawable.height = pScreen->height;
	REGION_INIT (pScreen, &pWin->winSize, &box, 1);
	REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
	REGION_RESET(pScreen, &pWin->borderClip, &box);
	REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
    }
    else
    {
	REGION_EMPTY(pScreen, &pWin->borderClip);
	REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
    }
    
    ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
    
    if (WasViewable)
    {
	if (pWin->backStorage)
	{
	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
	}

	if (pWin->firstChild)
	{
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
							   pWin->firstChild,
							   (WindowPtr *)NULL);
	}
	else
	{
	    (*pScreen->MarkWindow) (pWin);
	    anyMarked = TRUE;
	}

#ifdef DO_SAVE_UNDERS
	if (DO_SAVE_UNDERS(pWin))
	{
	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
	}
#endif /* DO_SAVE_UNDERS */

	if (anyMarked)
	    (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
    }

    if (pWin->backStorage &&
	((pWin->backingStore == Always) || WasViewable))
    {
	if (!WasViewable)
	    pOldClip = &pWin->clipList; /* a convenient empty region */
	bsExposed = (*pScreen->TranslateBackingStore)
			     (pWin, 0, 0, pOldClip,
			      pWin->drawable.x, pWin->drawable.y);
	if (WasViewable)
	    REGION_DESTROY(pScreen, pOldClip);
	if (bsExposed)
	{
	    RegionPtr	valExposed = NullRegion;
    
	    if (pWin->valdata)
		valExposed = &pWin->valdata->after.exposed;
	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
	    if (valExposed)
		REGION_EMPTY(pScreen, valExposed);
	    REGION_DESTROY(pScreen, bsExposed);
	}
    }
    if (WasViewable)
    {
	if (anyMarked)
	    (*pScreen->HandleExposures)(pWin);
#ifdef DO_SAVE_UNDERS
	if (dosave)
	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
#endif /* DO_SAVE_UNDERS */
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
#endif	/* !FB_OLD_SCREEN */
}
Example #18
0
Bool
xglSyncBits (DrawablePtr pDrawable,
	     BoxPtr	 pExtents)
{
    RegionRec region;
    BoxRec    box;

    XGL_DRAWABLE_PIXMAP (pDrawable);
    XGL_PIXMAP_PRIV (pPixmap);

    if (pPixmapPriv->allBits)
	return xglMapPixmapBits (pPixmap);

    if (pPixmapPriv->target == xglPixmapTargetIn && pExtents)
    {
	box.x1 = 0;
	box.y1 = 0;
	box.x2 = pPixmap->drawable.width;
	box.y2 = pPixmap->drawable.height;
	if (pExtents->x1 > box.x1)
	    box.x1 = pExtents->x1;
	if (pExtents->y1 > box.y1)
	    box.y1 = pExtents->y1;
	if (pExtents->x2 < box.x2)
	    box.x2 = pExtents->x2;
	if (pExtents->y2 < box.y2)
	    box.y2 = pExtents->y2;

	if (box.x2 <= box.x1 || box.y2 <= box.y1)
	    return xglMapPixmapBits (pPixmap);

	if (REGION_NOTEMPTY (pDrawable->pScreen, &pPixmapPriv->bitRegion))
	{
	    switch (RECT_IN_REGION (pDrawable->pScreen,
				    &pPixmapPriv->bitRegion,
				    &box)) {
	    case rgnIN:
		REGION_INIT (pDrawable->pScreen, &region, NullBox, 0);
		break;
	    case rgnOUT:
		REGION_INIT (pDrawable->pScreen, &region, &box, 1);
		REGION_UNION (pDrawable->pScreen,
			      &pPixmapPriv->bitRegion, &pPixmapPriv->bitRegion,
			      &region);
		break;
	    case rgnPART:
		REGION_INIT (pDrawable->pScreen, &region, &box, 1);
		REGION_SUBTRACT (pDrawable->pScreen, &region, &region,
				 &pPixmapPriv->bitRegion);
		REGION_UNION (pDrawable->pScreen,
			      &pPixmapPriv->bitRegion, &pPixmapPriv->bitRegion,
			      &region);
		break;
	    }
	}
	else
	{
	    REGION_INIT (pDrawable->pScreen, &region, &box, 1);
	    REGION_SUBTRACT (pDrawable->pScreen, &pPixmapPriv->bitRegion,
			     &region, &pPixmapPriv->bitRegion);
	}

	if (REGION_NUM_RECTS (&pPixmapPriv->bitRegion) == 1)
	{
	    BoxPtr pBox;

	    pBox = REGION_RECTS (&pPixmapPriv->bitRegion);

	    if (pBox->x1 <= 0			    &&
		pBox->y1 <= 0			    &&
		pBox->x2 >= pPixmap->drawable.width &&
		pBox->y2 >= pPixmap->drawable.height)
		pPixmapPriv->allBits = TRUE;
	}
    }
    else
    {
	box.x1 = 0;
	box.y1 = 0;
	box.x2 = pPixmap->drawable.width;
	box.y2 = pPixmap->drawable.height;

	REGION_INIT (pDrawable->pScreen, &region, &box, 1);
	REGION_SUBTRACT (pDrawable->pScreen, &region, &region,
			 &pPixmapPriv->bitRegion);

	pPixmapPriv->allBits = TRUE;
    }

    if (!pPixmapPriv->buffer)
	if (!xglAllocatePixmapBits (pPixmap, XGL_PIXMAP_USAGE_HINT_DEFAULT))
	    return FALSE;

    if (REGION_NOTEMPTY (pDrawable->pScreen, &region) && pPixmapPriv->surface)
    {
	glitz_pixel_format_t format;
	BoxPtr		     pBox;
	BoxPtr		     pExt;
	int		     nBox;

	if (!xglSyncSurface (pDrawable))
	    FatalError (XGL_SW_FAILURE_STRING);

	xglUnmapPixmapBits (pPixmap);

	pBox = REGION_RECTS (&region);
	nBox = REGION_NUM_RECTS (&region);
	pExt = REGION_EXTENTS (pDrawable->pScreen, &region);

	format.fourcc  = GLITZ_FOURCC_RGB;
	format.masks   = pPixmapPriv->pVisual->pPixel->masks;
	format.xoffset = pExt->x1;

	if (pPixmapPriv->stride < 0)
	{
	    format.skip_lines	  = pPixmap->drawable.height - pExt->y2;
	    format.bytes_per_line = -pPixmapPriv->stride;
	    format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
	}
	else
	{
	    format.skip_lines	  = pExt->y1;
	    format.bytes_per_line = pPixmapPriv->stride;
	    format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
	}

	glitz_surface_set_clip_region (pPixmapPriv->surface,
				       0, 0, (glitz_box_t *) pBox, nBox);

	glitz_get_pixels (pPixmapPriv->surface,
			  pExt->x1,
			  pExt->y1,
			  pExt->x2 - pExt->x1,
			  pExt->y2 - pExt->y1,
			  &format,
			  pPixmapPriv->buffer);

	glitz_surface_set_clip_region (pPixmapPriv->surface, 0, 0, NULL, 0);
    }

    REGION_UNINIT (pDrawable->pScreen, &region);

    if (pPixmapPriv->allBits)
    {
	box.x1 = 0;
	box.y1 = 0;
	box.x2 = pPixmap->drawable.width;
	box.y2 = pPixmap->drawable.height;

	REGION_UNINIT (pDrawable->pScreen, &pPixmapPriv->bitRegion);
	REGION_INIT (pDrawable->pScreen, &pPixmapPriv->bitRegion, &box, 1);
    }

    return xglMapPixmapBits (pPixmap);
}
Example #19
0
void
cfb8_32WidCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
	ScreenPtr pScreen = pWin->drawable.pScreen;
	cfb8_32WidScreenPtr pScreenPriv = 
		CFB8_32WID_GET_SCREEN_PRIVATE(pScreen);
	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
	PixmapPtr pPixChildren;
	DDXPointPtr ppt, pptSrc;
	RegionRec rgnDst, rgnOther, rgnPixmap;
	BoxPtr pbox;
	int i, nbox, dx, dy, other_bpp;

	REGION_NULL(pScreen, &rgnDst);

	dx = ptOldOrg.x - pWin->drawable.x;
	dy = ptOldOrg.y - pWin->drawable.y;
	REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
	REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);

	if ((nbox = REGION_NUM_RECTS(&rgnDst)) == 0) {
		/* Nothing to render. */
		REGION_UNINIT(pScreen, &rgnDst);
		return;
	}

	/* First, copy the WID plane for the whole area. */
	pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec));
	if(pptSrc) {
		pbox = REGION_RECTS(&rgnDst);
		for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
			ppt->x = pbox->x1 + dx;
			ppt->y = pbox->y1 + dy;
		}

		pScreenPriv->WIDOps->WidCopyArea((DrawablePtr)pScreenPriv->pixWid,
						 &rgnDst, pptSrc);

		DEALLOCATE_LOCAL(pptSrc);
	}

	/* Next, we copy children which have a different
	 * bpp than pWin into a temporary pixmap.  We will
	 * toss this pixmap back onto the framebuffer before
	 * we return.
	 */
	if (pWin->drawable.bitsPerPixel == 8)
		other_bpp = pScrn->bitsPerPixel;
	else
		other_bpp = 8;

	REGION_NULL(pScreen, &rgnOther);
	SegregateChildrenBpp(pWin, &rgnOther, 0,
			     other_bpp, pWin->drawable.bitsPerPixel);
	pPixChildren = NULL;
	if (REGION_NOTEMPTY(pScreen, &rgnOther)) {
		REGION_INTERSECT(pScreen, &rgnOther, &rgnOther, prgnSrc);
		nbox = REGION_NUM_RECTS(&rgnOther);
		if (nbox) {
			int width = rgnOther.extents.x2 - rgnOther.extents.x1;
			int height = rgnOther.extents.y2 - rgnOther.extents.y1;
			int depth = (other_bpp == 8) ? 8 : pScrn->depth;

			if (other_bpp == 8)
				pPixChildren = cfbCreatePixmap(pScreen, width, height, depth);
			else
				pPixChildren = cfb32CreatePixmap(pScreen, width, height, depth);
		}
		if (nbox &&
		    pPixChildren &&
		    (pptSrc = (DDXPointPtr) ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
			pbox = REGION_RECTS(&rgnOther);
			for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
				ppt->x = pbox->x1 + dx;
				ppt->y = pbox->y1 + dy;
			}

			REGION_NULL(pScreen, &rgnPixmap);
			REGION_COPY(pScreen, &rgnPixmap, &rgnOther);
			REGION_TRANSLATE(pScreen, &rgnPixmap, -(rgnOther.extents.x1), -(rgnOther.extents.y1));

			if (other_bpp == 8)
				cfbDoBitbltCopy((DrawablePtr)pScreenPriv->pix8,
						(DrawablePtr)pPixChildren,
						GXcopy, &rgnPixmap, pptSrc, ~0L);
			else
				cfb32DoBitbltCopy((DrawablePtr)pScreenPriv->pix32,
						  (DrawablePtr)pPixChildren,
						  GXcopy, &rgnPixmap, pptSrc, ~0L);

			REGION_UNINIT(pScreen, &rgnPixmap);

			DEALLOCATE_LOCAL(pptSrc);
		}

		REGION_SUBTRACT(pScreen, &rgnDst, &rgnDst, &rgnOther);
	}

	/* Now copy the parent along with all child windows using the same depth. */
	nbox = REGION_NUM_RECTS(&rgnDst);
	if(nbox &&
	   (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
		pbox = REGION_RECTS(&rgnDst);
		for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
			ppt->x = pbox->x1 + dx;
			ppt->y = pbox->y1 + dy;
		}

		if (pWin->drawable.bitsPerPixel == 8)
			cfbDoBitbltCopy((DrawablePtr)pScreenPriv->pix8,
					(DrawablePtr)pScreenPriv->pix8,
					GXcopy, &rgnDst, pptSrc, ~0L);
		else
			cfb32DoBitbltCopy((DrawablePtr)pScreenPriv->pix32,
					  (DrawablePtr)pScreenPriv->pix32,
					  GXcopy, &rgnDst, pptSrc, ~0L);

		DEALLOCATE_LOCAL(pptSrc);
	}

	REGION_UNINIT(pScreen, &rgnDst);

	if (pPixChildren) {
		nbox = REGION_NUM_RECTS(&rgnOther);
		pptSrc = (DDXPointPtr) ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec));
		if (pptSrc) {
			pbox = REGION_RECTS(&rgnOther);
			for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
				ppt->x = pbox->x1 - rgnOther.extents.x1;
				ppt->y = pbox->y1 - rgnOther.extents.y1;
			}

			if (other_bpp == 8)
				cfbDoBitbltCopy((DrawablePtr)pPixChildren,
						(DrawablePtr)pScreenPriv->pix8,
						GXcopy, &rgnOther, pptSrc, ~0L);
			else
				cfb32DoBitbltCopy((DrawablePtr)pPixChildren,
						  (DrawablePtr)pScreenPriv->pix32,
						  GXcopy, &rgnOther, pptSrc, ~0L);

			DEALLOCATE_LOCAL(pptSrc);
		}

		if (other_bpp == 8)
			cfbDestroyPixmap(pPixChildren);
		else
			cfb32DestroyPixmap(pPixChildren);
	}
	REGION_UNINIT(pScreen, &rgnOther);
}
Example #20
0
static void send_update(void)
{
  CL_SLOT *cl = (CL_SLOT *)cur_slot;
  BoxRec fb_rect;
  RegionRec fb_region, clip_region, outer_region;
  CARD8 msg_hdr[4] = {
    0, 0, 0, 1
  };
  CARD8 rect_hdr[12];
  int num_copy_rects, num_pending_rects, num_all_rects;
  int raw_bytes = 0, hextile_bytes = 0;
  int i, idx, rev_order;
  static int counter = 0;

#ifdef NETLOGGER
  aio_set_serial_number(&cl->s, cl->serial_number);
#endif

  counter++;
  vncspuLog(1, "Begin send update %d", counter);

  CRASSERT(vnc_spu.serverBuffer);

  /*crDebug("Enter send_update to %s", cur_slot->name);*/

  /* check if clipping has changed since we got the pixels and update
   * the pending region if needed.
   */
  if (NewClip) {
     /*crDebug("Getting updated cliprects");*/
     vncspuGetScreenRects(&cl->pending_region);
     num_pending_rects = REGION_NUM_RECTS(&cl->pending_region);
     /*crDebug("Now, %d rects", num_pending_rects);*/
     if (num_pending_rects == 0 && cl->enable_frame_sync) {
        /* always need to send _something_ for framesync to work */
        BoxRec b;
        b.x1 = 0;
        b.y1 = 0;
        b.x2 = 1;
        b.y2 = 1;
        REGION_UNINIT(&cl->pending_region);
        REGION_INIT(&cl->pending_region, &b, 1);
     }
     NewClip = 0;
  }
  /*PrintRegion("Sending", &cl->pending_region);*/


  /* Process framebuffer size change. */
  if (cl->newfbsize_pending) {
    /* Update framebuffer size, clear newfbsize_pending flag. */
    cl->fb_width = g_screen_info.width;
    cl->fb_height = g_screen_info.height;
    cl->newfbsize_pending = 0;
    log_write(LL_DEBUG, "Applying new framebuffer size (%dx%d) to %s",
              (int)cl->fb_width, (int)cl->fb_height, cur_slot->name);
    /* In any case, mark all the framebuffer contents as changed. */
    fb_rect.x1 = 0;
    fb_rect.y1 = 0;
    fb_rect.x2 = cl->fb_width;
    fb_rect.y2 = cl->fb_height;
    REGION_INIT(&fb_region, &fb_rect, 1);
    REGION_COPY(&cl->pending_region, &fb_region);
    REGION_UNINIT(&fb_region);
    REGION_EMPTY(&cl->copy_region);
    /* If NewFBSize is supported by the client, send only NewFBSize
       pseudo-rectangle, pixel data will be sent in the next update. */
    if (cl->enable_newfbsize) {
      send_newfbsize();
      vncspuUnlockFrameBuffer();
      return;
    }
  } else {
    /* Exclude CopyRect areas covered by pending_region. */
    REGION_SUBTRACT(&cl->copy_region, &cl->copy_region, &cl->pending_region);
  }

#if 00
  if (cl->enable_cliprects_enc && cl->new_cliprects) {
    send_new_cliprects();
    vncspuUnlockFrameBuffer();
    cl->new_cliprects = 0;
    return;
  }
#endif

  /* Clip regions to the rectangle requested by the client. */
  REGION_INIT(&clip_region, &cl->update_rect, 1);

  REGION_INTERSECT(&cl->pending_region, &cl->pending_region, &clip_region);
  if (REGION_NOTEMPTY(&cl->copy_region)) {
    REGION_INTERSECT(&cl->copy_region, &cl->copy_region, &clip_region);

    REGION_INIT(&outer_region, NullBox, 8);
    REGION_COPY(&outer_region, &cl->copy_region);
    REGION_TRANSLATE(&clip_region, cl->copy_dx, cl->copy_dy);
    REGION_INTERSECT(&cl->copy_region, &cl->copy_region, &clip_region);
    REGION_SUBTRACT(&outer_region, &outer_region, &cl->copy_region);
    REGION_UNION(&cl->pending_region, &cl->pending_region, &outer_region);
    REGION_UNINIT(&outer_region);
  }
  REGION_UNINIT(&clip_region);

  /* Reduce the number of rectangles if possible. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    region_pack(&cl->pending_region, 32);
  } else {
    region_pack(&cl->pending_region, 12);
  }

  /* Compute the number of rectangles in regions. */
  num_pending_rects = REGION_NUM_RECTS(&cl->pending_region);
  num_copy_rects = REGION_NUM_RECTS(&cl->copy_region);
  num_all_rects = num_pending_rects + num_copy_rects;
  if (num_all_rects == 0) {
    vncspuUnlockFrameBuffer();
    return;
  }

  log_write(LL_DEBUG, "Sending framebuffer update (min %d rects) to %s",
            num_all_rects, cur_slot->name);

  /* Prepare and send FramebufferUpdate message header. */
  /* FIXME: Enable Tight encoding even if LastRect is not supported. */
  /* FIXME: Do not send LastRect if all the rectangles are CopyRect. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    buf_put_CARD16(&msg_hdr[2], 0xFFFF);
  } else {
    buf_put_CARD16(&msg_hdr[2], num_all_rects);
  }
  aio_write(NULL, msg_hdr, 4);

  /* Determine the order in which CopyRect rectangles should be sent. */
  rev_order = (cl->copy_dy > 0 || (cl->copy_dy == 0 && cl->copy_dx > 0));

  /* For each CopyRect rectangle: */
  for (i = 0; i < num_copy_rects; i++) {
    FB_RECT rect;
    AIO_BLOCK *block;
    idx = (rev_order) ? num_copy_rects - i - 1 : i;
    rect.x = REGION_RECTS(&cl->copy_region)[idx].x1;
    rect.y = REGION_RECTS(&cl->copy_region)[idx].y1;
    rect.w = REGION_RECTS(&cl->copy_region)[idx].x2 - rect.x;
    rect.h = REGION_RECTS(&cl->copy_region)[idx].y2 - rect.y;
    rect.src_x = rect.x - cl->copy_dx;
    rect.src_y = rect.y - cl->copy_dy;
    rect.enc = RFB_ENCODING_COPYRECT;
    log_write(LL_DEBUG, "Sending CopyRect rectangle %dx%d at %d,%d to %s",
              (int)rect.w, (int)rect.h, (int)rect.x, (int)rect.y,
              cur_slot->name);

    /* Prepare the CopyRect rectangle. */
    block = rfb_encode_copyrect_block(cl, &rect);

    /* Send the rectangle.
       FIXME: Check for block == NULL? */
    aio_write_nocopy(NULL, block);
  }

  if (cl->enc_prefer == RFB_ENCODING_TIGHT) {
    /* needed for successful caching of zlib-compressed data (tight) */
    rfb_reset_tight_encoder(cl);
  }

  if (num_pending_rects) {
    /* Lock around fb access so other thread doesn't change contents while
     * we're encoding.
     */
#ifdef NETLOGGER
    if (vnc_spu.netlogger_url) {
      NL_info("vncspu", "spu.encode.begin",
              "NODE=s NUMBER=i", vnc_spu.hostname, cl->serial_number);
    }
#endif

    /* For each of the usual pending rectangles: */
    for (i = 0; i < num_pending_rects; i++) {
      FB_RECT rect;
      AIO_BLOCK *block;
			/*
      crDebug("sending rect %d of %d: %d, %d .. %d, %d", i, num_pending_rects,
              REGION_RECTS(&cl->pending_region)[i].x1,
              REGION_RECTS(&cl->pending_region)[i].y1,
              REGION_RECTS(&cl->pending_region)[i].x2,
              REGION_RECTS(&cl->pending_region)[i].y2);
			*/
      rect.x = REGION_RECTS(&cl->pending_region)[i].x1;
      rect.y = REGION_RECTS(&cl->pending_region)[i].y1;
      rect.w = REGION_RECTS(&cl->pending_region)[i].x2 - rect.x;
      rect.h = REGION_RECTS(&cl->pending_region)[i].y2 - rect.y;
      log_write(LL_DEBUG, "Sending rectangle %dx%d at %d,%d to %s enc 0x%x",
                (int)rect.w, (int)rect.h, (int)rect.x, (int)rect.y,
                cur_slot->name, cl->enc_prefer);

      if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
        /* Use Tight encoding */
        rect.enc = RFB_ENCODING_TIGHT;
        /* lock to prevent glReadPixels in other thread changing data */
        rfb_encode_tight(cl, &rect);
        continue;                 /* Important! */
      } else if (cl->enc_prefer == RFB_ENCODING_RAW24) {
        rect.enc = RFB_ENCODING_RAW24;
        block = rfb_encode_raw24_block(cl, &rect);
      } else if ( cl->enc_prefer != RFB_ENCODING_RAW &&
                  cl->enc_enable[RFB_ENCODING_HEXTILE] ) {
        /* Use Hextile encoding */
        rect.enc = RFB_ENCODING_HEXTILE;
        block = rfb_encode_hextile_block(cl, &rect);
        if (block != NULL) {
          hextile_bytes += block->data_size;
          raw_bytes += rect.w * rect.h * (cl->format.bits_pixel / 8);
        }
      } else {
        /* Use Raw encoding */
        rect.enc = RFB_ENCODING_RAW;
        if (vnc_spu.half_rez) {
           block = rfb_encode_raw_block_halfrez(cl, &rect);
        }
        else {
           block = rfb_encode_raw_block(cl, &rect);
        }
      }

      /* Send the rectangle.
         FIXME: Check for block == NULL? */
      aio_write_nocopy(NULL, block);
    }

  } /* if num_pending_rects */


  REGION_EMPTY(&cl->pending_region);
  REGION_EMPTY(&cl->copy_region);

  /* Send LastRect marker. */
  if (cl->enc_prefer == RFB_ENCODING_TIGHT && cl->enable_lastrect) {
    FB_RECT rect;
    rect.x = rect.y = rect.w = rect.h = 0;
    rect.enc = RFB_ENCODING_LASTRECT;
    put_rect_header(rect_hdr, &rect);
    aio_write(NULL, rect_hdr, 12);
  }

  /* Set the last block's callback function */
  /* All prev blocks had NULL callbacks */
  assert(cur_slot->outqueue_last);
  if (cur_slot->outqueue_last) {
    cur_slot->outqueue_last->func = wf_client_update_finished;
  }

  /* Something has been queued for sending. */
  cl->update_in_progress = 1;
  cl->update_requested = 0;

#ifdef NETLOGGER
  if (vnc_spu.netlogger_url) {
    NL_info("vncspu", "spu.encode.end",
            "NODE=s NUMBER=i", vnc_spu.hostname, cl->serial_number);
  }
  aio_set_serial_number(&cl->s, 0);
#endif

  vncspuUnlockFrameBuffer(); /* encoder done with buffer */

  /*crDebug("Leave send_update");*/

  vncspuLog(1, "End send update %d", counter);
}