コード例 #1
0
ファイル: winrgn.c プロジェクト: ghaerr/microwindows
/*
 * Note: The behavior is correct even if src and dest regions are the same.
 */
INT WINAPI
CombineRgn(HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode)
{
    MWRGNOBJ *destObj = (MWRGNOBJ *) GDI_GetObjPtr( hDest, OBJ_REGION);
    INT result = ERRORREGION;

    /*TRACE(region, " %04x,%04x -> %04x mode=%x\n", hSrc1, hSrc2, hDest,mode);*/

    if (destObj)
    {
	MWRGNOBJ *src1Obj = (MWRGNOBJ *) GDI_GetObjPtr( hSrc1, OBJ_REGION);

	if (src1Obj)
	{
	    /*TRACE(region, "dump:\n");
	    if(TRACE_ON(region)) 
	        REGION_DumpRegion(src1Obj->rgn);*/
	    if (mode == RGN_COPY)
	    {
		GdCopyRegion( destObj->rgn, src1Obj->rgn );
		result = destObj->rgn->type;
	    }
	    else
	    {
		MWRGNOBJ *src2Obj = (MWRGNOBJ *) GDI_GetObjPtr( hSrc2, OBJ_REGION);

		if (src2Obj)
		{
		    /*TRACE(region, "dump:\n");
		    if(TRACE_ON(region)) 
		        REGION_DumpRegion(src2Obj->rgn);*/
		    switch (mode)
		    {
		    case RGN_AND:
			GdIntersectRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn);
			break;
		    case RGN_OR:
			GdUnionRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
			break;
		    case RGN_XOR:
			GdXorRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
			break;
		    case RGN_DIFF:
			GdSubtractRegion( destObj->rgn, src1Obj->rgn, src2Obj->rgn );
			break;
		    }
		    result = destObj->rgn->type;
		}
	    }
	}
	/*TRACE(region, "dump:\n");
	if(TRACE_ON(region)) 
	    REGION_DumpRegion(destObj->rgn);*/
    }
    return result;
}
コード例 #2
0
ファイル: srvutil.c プロジェクト: EPiCS/reconos_v2
/*
 * Prepare to do drawing in a window or pixmap using the specified
 * graphics context.  Returns the drawable pointer if successful,
 * and the type of drawing id that was supplied.  Returns the special value
 * GR_DRAW_TYPE_NONE if an error is generated, or if drawing is useless.
 */
GR_DRAW_TYPE GsPrepareDrawing(GR_DRAW_ID id, GR_GC_ID gcid, GR_DRAWABLE **retdp)
{
	GR_WINDOW	*wp;		/* found window */
        GR_PIXMAP       *pp;            /* found pixmap */
	GR_GC		*gcp;		/* found graphics context */
	GR_FONT		*fontp;
	GR_REGION	*regionp;	/* user clipping region */
	MWCLIPREGION	*reg;
	PMWFONT		pf;

	*retdp = NULL;

	gcp = GsFindGC(gcid);
	if (gcp == NULL)
		return GR_DRAW_TYPE_NONE;

	/*
	 * If the graphics context is not the current one, then
	 * make it the current one and remember to update it.
	 */
	if (gcp != curgcp) {
		curgcp = gcp;
		gcp->changed = GR_TRUE;
	}

	/*
	 * Look for window or pixmap id
	 */
        pp = NULL;
	wp = GsFindWindow(id);
	if (wp == NULL) {
	        pp = GsFindPixmap(id);
	        if (pp == NULL)
		          return GR_DRAW_TYPE_NONE;
	   
#if DYNAMICREGIONS
		reg = GdAllocRectRegion(0, 0, pp->psd->xvirtres,
			pp->psd->yvirtres);
		/* intersect with user region if any*/
		if (gcp->regionid) {
			regionp = GsFindRegion(gcp->regionid);
			if (regionp)
				GdIntersectRegion(reg, reg, regionp->rgn);
		}
		GdSetClipRegion(pp->psd, reg);
#else
		{
		MWCLIPRECT	cliprect;
		/* FIXME: setup pixmap clipping, different from windows*/
	        cliprect.x = 0;
	        cliprect.y = 0;
	        cliprect.width = pp->psd->xvirtres;
	        cliprect.height = pp->psd->yvirtres;
	        GdSetClipRects(pp->psd, 1, &cliprect);
		}
#endif
		/* reset clip cache for next window draw*/
		clipwp = NULL;
	} else {
   
	        if (!wp->output) {
		          GsError(GR_ERROR_INPUT_ONLY_WINDOW, id);
		          return GR_DRAW_TYPE_NONE;
		}

	        if (wp->unmapcount)
		          return GR_DRAW_TYPE_NONE;
	   
	        /*
		 * If the window is not the currently clipped one,
		 * then make it the current one and define its clip rectangles.
		 */
	        if (wp != clipwp || gcp->changed) {
			/* find user region for intersect*/
			if (gcp->regionid)
				regionp = GsFindRegion(gcp->regionid);
			else regionp = NULL;

			/*
			 * Special handling if user region is not at offset 0,0
			 */
			if (regionp && (gcp->xoff || gcp->yoff)) {
				MWCLIPREGION *local = GdAllocRegion();

				GdCopyRegion(local, regionp->rgn);
				GdOffsetRegion(local, gcp->xoff, gcp->yoff);

				GsSetClipWindow(wp, local,  
					gcp->mode & ~GR_MODE_DRAWMASK);

				GdDestroyRegion(local);
			  } else {
				GsSetClipWindow(wp, regionp? regionp->rgn: NULL,
					gcp->mode & ~GR_MODE_DRAWMASK);
			  }
		}
	}

	/*
	 * If the graphics context has been changed, then tell the
	 * device driver about it.
	 */
	if (gcp->changed) {
		GdSetForeground(GdFindColor(gcp->foreground));
		GdSetBackground(GdFindColor(gcp->background));
		GdSetMode(gcp->mode & GR_MODE_DRAWMASK);
		GdSetUseBackground(gcp->usebackground);
		fontp = GsFindFont(gcp->fontid);
		pf = fontp? fontp->pfont: stdfont;
		GdSetFont(pf);
		gcp->changed = GR_FALSE;
	}

	*retdp = wp? (GR_DRAWABLE *)wp: (GR_DRAWABLE *)pp;
	return wp? GR_DRAW_TYPE_WINDOW: GR_DRAW_TYPE_PIXMAP;
}
コード例 #3
0
ファイル: winclip2.c プロジェクト: BadrElh/microwindows
/*
 * Set the clip rectangles for a window taking into account other
 * windows that may be obscuring it.  The windows that may be obscuring
 * this one are the siblings of each direct ancestor which are higher
 * in priority than those ancestors.  Also, each parent limits the visible
 * area of the window.
 */
void
MwSetClipWindow(HDC hdc)
{
	HWND		wp = hdc->hwnd;
	HWND		pwp;		/* parent window */
	HWND		sibwp;		/* sibling windows */
	MWCOORD		diff;		/* difference in coordinates */
	PRECT		prc;		/* client or window rectangle*/
	MWCLIPREGION	*vis, *r;
	MWCOORD		x, y, width, height;

	/*
	 * Start with the rectangle for the complete window.
	 * We will then cut pieces out of it as needed.
	 */
	prc = MwIsClientDC(hdc)? &wp->clirect: &wp->winrect;
	x = prc->left;
	y = prc->top;
	width = prc->right - prc->left;
	height = prc->bottom - prc->top;

	/*
	 * First walk upwards through all parent windows,
	 * and restrict the visible part of this window to the part
	 * that shows through all of those parent windows client areas.
	 */
	pwp = wp;
	while (pwp != rootwp) {
		pwp = pwp->parent;

		diff = pwp->clirect.left - x;
		if (diff > 0) {
			width -= diff;
			x = pwp->clirect.left;
		}

		diff = pwp->clirect.right - (x + width);
		if (diff < 0)
			width += diff;

		diff = pwp->clirect.top - y;
		if (diff > 0) {
			height -= diff;
			y = pwp->clirect.top;
		}

		diff = pwp->clirect.bottom - (y + height);
		if (diff < 0)
			height += diff;
	}

	/*
	 * If the window is completely clipped out of view, then
	 * set the clipping region to indicate that.
	 */
	if (width <= 0 || height <= 0) {
		GdSetClipRegion(hdc->psd, NULL);
		return;
	} 

	/*
	 * Allocate initial vis region to parent-clipped size of window
	 */
	vis = GdAllocRectRegion(x, y, x+width, y+height);

	/* 
	 * Allocate temp region
	 */
	r = GdAllocRegion();

	/*
	 * Now examine all windows that obscure this window, and
	 * for each obscuration, break up the clip rectangles into
	 * the smaller pieces that are still visible.  The windows
	 * that can obscure us are the earlier siblings of all of
	 * our parents. When clipping the root window, search all children.
 	 */
	pwp = wp;
	while (pwp != NULL) {
		wp = pwp;
		pwp = wp->parent;
		if(!pwp) {
			/* We're clipping the root window*/
			if(hdc->flags & DCX_CLIPCHILDREN)
				/* start with root's children*/
				sibwp = rootwp->children;
			else sibwp = NULL;	/* no search*/
			wp = NULL;		/* search all root's children*/
		} else {
			if(hdc->flags & DCX_CLIPSIBLINGS)
				sibwp = pwp->children;
			else sibwp = wp;	/* no search*/
		}
		for (; sibwp != wp; sibwp = sibwp->siblings) {
			if (sibwp->unmapcount)
				continue;

			GdSetRectRegionIndirect(r, &sibwp->winrect);
			GdSubtractRegion(vis, vis, r);
		}

		/* if not clipping the root window, stop when you reach it*/
		if(pwp == rootwp)
			break;
	}

	/*
	 * If not the root window and we're going to be drawing
	 * in the client area, clip all children.  This is
	 * required for non-special paint handling for child windows.
	 * Non-client dc's don't clip children in order to get
	 * proper border clipping in the case of border-clipped children.
	 */
	wp = hdc->hwnd;
	if(wp != rootwp && MwIsClientDC(hdc)) {
		for (sibwp=wp->children; sibwp; sibwp = sibwp->siblings) {
			if (sibwp->unmapcount)
				continue;

			GdSetRectRegionIndirect(r, &sibwp->winrect);
			GdSubtractRegion(vis, vis, r);
		}
	}

#if UPDATEREGIONS
	/*
	 * Intersect with update region, unless requested not to.
	 */
	if(!(hdc->flags & DCX_EXCLUDEUPDATE))
		GdIntersectRegion(vis, vis, wp->update);
#endif
	/*
	 * Intersect with user region, if set.
	 */
	if (hdc->region)
		GdIntersectRegion(vis, vis, hdc->region->rgn);
	/*
	 * Set the clip region (later destroy handled by GdSetClipRegion)
	 */
	GdSetClipRegion(hdc->psd, vis);

	/*
	 * Destroy temp region
	 */
	GdDestroyRegion(r);
}
コード例 #4
0
ファイル: srvutil.c プロジェクト: ghaerr/microwindows
/*
 * Prepare to do drawing in a window or pixmap using the specified
 * graphics context.  Returns the drawable pointer if successful,
 * and the type of drawing id that was supplied.  Returns the special value
 * GR_DRAW_TYPE_NONE if an error is generated, or if drawing is useless.
 */
GR_DRAW_TYPE
GsPrepareDrawing(GR_DRAW_ID id, GR_GC_ID gcid, GR_DRAWABLE **retdp)
{
	GR_WINDOW	*wp;		/* found window */
	GR_PIXMAP	*pp;		/* found pixmap */
	GR_GC		*gcp;		/* found graphics context */
	GR_REGION	*regionp;	/* user clipping region */
	MWCLIPREGION*reg;

	*retdp = NULL;

	gcp = GsFindGC(gcid);
	if (gcp == NULL)
		return GR_DRAW_TYPE_NONE;

	/*
	 * If the graphics context is not the current one, then
	 * make it the current one and remember to update it.
	 */
	if (gcp != curgcp) {
		curgcp = gcp;
		gcp->changed = GR_TRUE;
	}

	/*
	 * Look for window or pixmap id
	 */
	pp = NULL;
	wp = GsFindWindow(id);
	if (wp == NULL) {
		pp = GsFindPixmap(id);
		if (pp == NULL)
				return GR_DRAW_TYPE_NONE;
havepixmap:
#if DYNAMICREGIONS
		reg = GdAllocRectRegion(0, 0, pp->psd->xvirtres, pp->psd->yvirtres);
		/* intersect with user region if any*/
		if (gcp->regionid) {
			regionp = GsFindRegion(gcp->regionid);
			if (regionp) {
				/* handle pixmap offsets*/
				if (gcp->xoff || gcp->yoff) {
					MWCLIPREGION *local = GdAllocRegion();

					GdCopyRegion(local, regionp->rgn);
					GdOffsetRegion(local, gcp->xoff, gcp->yoff);
					GdIntersectRegion(reg, reg, local);
					GdDestroyRegion(local);
				} else
					GdIntersectRegion(reg, reg, regionp->rgn);
			}
		}
		GdSetClipRegion(pp->psd, reg);
#else
		{
			MWCLIPRECT	cliprect;
			/* FIXME: setup pixmap clipping, different from windows*/
	        cliprect.x = 0;
	        cliprect.y = 0;
	        cliprect.width = pp->psd->xvirtres;
	        cliprect.height = pp->psd->yvirtres;
	        GdSetClipRects(pp->psd, 1, &cliprect);
		}
#endif
		/* reset clip cache for next window draw*/
		clipwp = NULL;
	} else {
		if (!wp->output) {
				GsError(GR_ERROR_INPUT_ONLY_WINDOW, id);
				return GR_DRAW_TYPE_NONE;
		}

		/* check if buffered window*/
		if (wp->props & GR_WM_PROPS_BUFFERED) {
			pp = wp->buffer;
			wp = NULL;
			goto havepixmap;		/* draw into pixmap buffer*/
		}

		if (!wp->realized)
				return GR_DRAW_TYPE_NONE;

		/*
		 * If the window is not the currently clipped one,
		 * then make it the current one and define its clip rectangles.
		 */
		if (wp != clipwp || gcp->changed) {
#if DYNAMICREGIONS
			/* find user region for intersect*/
			regionp = gcp->regionid? GsFindRegion(gcp->regionid): NULL;

		 	/* Special handling if user region is not at offset 0,0*/
			if (regionp && (gcp->xoff || gcp->yoff)) {
				MWCLIPREGION *local = GdAllocRegion();

				GdCopyRegion(local, regionp->rgn);
				GdOffsetRegion(local, gcp->xoff, gcp->yoff);

				GsSetClipWindow(wp, local, gcp->mode & ~GR_MODE_DRAWMASK);
				GdDestroyRegion(local);
			} else
				GsSetClipWindow(wp, regionp? regionp->rgn: NULL, gcp->mode & ~GR_MODE_DRAWMASK);
#else
				GsSetClipWindow(wp, NULL, gcp->mode & ~GR_MODE_DRAWMASK);
#endif /* DYNAMICREGIONS*/
		}
	}

	/*
	 * If the graphics context has been changed, then tell the
	 * device driver about it.
	 */
	if (gcp->changed) {
		PSD			psd = (wp ? wp->psd : pp->psd);
		uint32_t	mask;
		int			count;

		if (gcp->linestyle == GR_LINE_SOLID) {
			mask = 0;
			count = 0;
		} else {
			mask = gcp->dashmask;
			count = gcp->dashcount;
		}

		if (gcp->fgispixelval)
			GdSetForegroundPixelVal(psd, gcp->foreground);
		else
			GdSetForegroundColor(psd, gcp->foreground);

		if (gcp->bgispixelval)
			GdSetBackgroundPixelVal(psd, gcp->background);
		else
			GdSetBackgroundColor(psd, gcp->background);

		GdSetMode(gcp->mode & GR_MODE_DRAWMASK);
		GdSetUseBackground(gcp->usebackground);
		
#if MW_FEATURE_SHAPES
		GdSetDash(&mask, &count);
		GdSetFillMode(gcp->fillmode);
		GdSetTSOffset(gcp->ts_offset.x, gcp->ts_offset.y);

		switch(gcp->fillmode) {
		case GR_FILL_STIPPLE:
		case GR_FILL_OPAQUE_STIPPLE:
			GdSetStippleBitmap(gcp->stipple.bitmap, gcp->stipple.width, gcp->stipple.height);
			break;
		case GR_FILL_TILE:
			GdSetTilePixmap(gcp->tile.psd, gcp->tile.width, gcp->tile.height);
			break;
		}
#endif
		gcp->changed = GR_FALSE;
	}

	*retdp = wp? (GR_DRAWABLE *)wp: (GR_DRAWABLE *)pp;
	return wp? GR_DRAW_TYPE_WINDOW: GR_DRAW_TYPE_PIXMAP;
}
コード例 #5
0
ファイル: srvclip2.c プロジェクト: EPiCS/reconos_v2
/*
 * Set the clip rectangles for a window taking into account other
 * windows that may be obscuring it.  The windows that may be obscuring
 * this one are the siblings of each direct ancestor which are higher
 * in priority than those ancestors.  Also, each parent limits the visible
 * area of the window.  The clipping is not done if it is already up to
 * date of if the window is not outputtable.
 */
void
GsSetClipWindow(GR_WINDOW *wp, MWCLIPREGION *userregion, int flags)
{
	GR_WINDOW	*orgwp;		/* original window pointer */
	GR_WINDOW	*pwp;		/* parent window */
	GR_WINDOW	*sibwp;		/* sibling windows */
	GR_COORD	minx;		/* minimum clip x coordinate */
	GR_COORD	miny;		/* minimum clip y coordinate */
	GR_COORD	maxx;		/* maximum clip x coordinate */
	GR_COORD	maxy;		/* maximum clip y coordinate */
	GR_COORD	diff;		/* difference in coordinates */
	GR_SIZE		bs;		/* border size */
	GR_COORD	x, y, width, height;
	MWCLIPREGION	*vis, *r;

	if (wp->unmapcount || !wp->output)
		return;

	clipwp = wp;

	/*
	 * Start with the rectangle for the complete window.
	 * We will then cut pieces out of it as needed.
	 */
	x = wp->x;
	y = wp->y;
	width = wp->width;
	height = wp->height;

	/*
	 * First walk upwards through all parent windows,
	 * and restrict the visible part of this window to the part
	 * that shows through all of those parent windows.
	 */
	pwp = wp;
	while (pwp != rootwp) {
		pwp = pwp->parent;

		diff = pwp->x - x;
		if (diff > 0) {
			width -= diff;
			x = pwp->x;
		}

		diff = (pwp->x + pwp->width) - (x + width);
		if (diff < 0)
			width += diff;

		diff = pwp->y - y;
		if (diff > 0) {
			height -= diff;
			y = pwp->y;
		}

		diff = (pwp->y + pwp->height) - (y + height);
		if (diff < 0)
			height += diff;
	}

	/*
	 * If the window is completely clipped out of view, then
	 * set the clipping region to indicate that.
	 */
	if (width <= 0 || height <= 0) {
		GdSetClipRegion(clipwp->psd, NULL);
		return;
	}

	/*
	 * Allocate region to clipped size of window
	 */
	vis = GdAllocRectRegion(x, y, x+width, y+height);

	/* 
	 * Allocate temp region
	 */
	r = GdAllocRegion();

	/*
	 * Now examine all windows that obscure this window, and
	 * for each obscuration, break up the clip rectangles into
	 * the smaller pieces that are still visible.  The windows
	 * that can obscure us are the earlier siblings of all of
	 * our parents.
 	 */
	orgwp = wp;
	pwp = wp;
	while (pwp != NULL) {
		wp = pwp;
		pwp = wp->parent;

		if(!pwp) {
			/* We're clipping the root window*/
			if (!(flags & GR_MODE_EXCLUDECHILDREN))
				/* start with root's children*/
				sibwp = rootwp->children;
			else sibwp = NULL;	 /* no search*/
			wp = NULL;		 /* search all root's children*/
		} else {
			sibwp = pwp->children;	 /* clip siblings*/
		}

		for (; sibwp != wp; sibwp = sibwp->siblings) {
			if (sibwp->unmapcount || !sibwp->output)
				continue;

			bs = sibwp->bordersize;
			minx = sibwp->x - bs;
			miny = sibwp->y - bs;
			maxx = sibwp->x + sibwp->width + bs;
			maxy = sibwp->y + sibwp->height + bs;

			GdSetRectRegion(r, minx, miny, maxx, maxy);
			GdSubtractRegion(vis, vis, r);
		}

		/* if not clipping the root window, stop when you reach it*/
		if (pwp == rootwp)
			break;
	}

	wp = orgwp;
	/*
	 * If not the root window, clip all children.
	 * (Root window's children are are clipped above)
	 */
	if(wp != rootwp && !(flags & GR_MODE_EXCLUDECHILDREN)) {
		for (sibwp=wp->children; sibwp; sibwp = sibwp->siblings) {
			if (sibwp->unmapcount || !sibwp->output)
				continue;

			bs = sibwp->bordersize;
			minx = sibwp->x - bs;
			miny = sibwp->y - bs;
			maxx = sibwp->x + sibwp->width + bs;
			maxy = sibwp->y + sibwp->height + bs;

			GdSetRectRegion(r, minx, miny, maxx, maxy);
			GdSubtractRegion(vis, vis, r);
		}
	}

	/*
	 * Intersect with user region, if set.
	 */
	if (userregion) {
		/* temporarily offset region by window coordinates*/
		GdOffsetRegion(userregion, wp->x, wp->y);
		GdIntersectRegion(vis, vis, userregion);
		GdOffsetRegion(userregion, -wp->x, -wp->y);
	}

	/*
	 * Set the clip region (later destroy handled by GdSetClipRegion)
	 */
	GdSetClipRegion(clipwp->psd, vis);

	/*
	 * Destroy temp region
	 */
	GdDestroyRegion(r);
}