⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srvfunc.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:
		GsError(GR_ERROR_ILLEGAL_ON_ROOT_WINDOW, wid);
		return;
	}
	if ((width <= 0) || (height <= 0)) {
		GsError(GR_ERROR_BAD_WINDOW_SIZE, wid);
		return;
	}

	if ((wp->width == width) && (wp->height == height))
		return;

	if (wp->unmapcount || !wp->output) {
		wp->width = width;
		wp->height = height;
		return;
	}

	/*
	 * This should be optimized to not require redrawing of the window
	 * when possible.
	 */
	GsWpUnmapWindow(wp, GR_TRUE);
	wp->width = width;
	wp->height = height;
	GsWpMapWindow(wp, GR_FALSE);
	GsDeliverUpdateEvent(wp, GR_UPDATE_SIZE, wp->x, wp->y, width, height);
}

/* set unmapcount for a window and all its children*/
static void
SetUnmapCountTree(GR_WINDOW *wp, int value, GR_BOOL increment)
{
	GR_WINDOW *	childwp;

	if (increment)
		wp->unmapcount += value;
	else wp->unmapcount = value;

	for (childwp = wp->children; childwp; childwp = childwp->siblings)
		SetUnmapCountTree(childwp, value, increment);
}

/*
 * Reparent window to new parent, position at passed x, y
 *
 * NOTE: currently, the new parent must be mapped before
 * reparenting, or the children of the newly parented window
 * will have bad unmapcount values due to the GrMapWindow
 * being called on the parent afterwards, and chaining down
 * through the children.
 */
void
GrReparentWindow(GR_WINDOW_ID wid, GR_WINDOW_ID pwid, GR_COORD x, GR_COORD y)
{
	GR_WINDOW	*wp;		/* window structure */
	GR_WINDOW	*pwp;		/* parent window structure */
	GR_WINDOW	**mysibptr;	/* handle to my sibling ptr */
	GR_COORD	offx, offy;
	GR_BOOL		wasmapped;

	wp = GsFindWindow(wid);
	pwp = GsFindWindow(pwid);
	if (wp == NULL || pwp == NULL || wp == pwp)
		return;
	if (wp == rootwp) {
		GsError(GR_ERROR_ILLEGAL_ON_ROOT_WINDOW, wid);
		return;
	}

	x += pwp->x;
	y += pwp->y;
	offx = x - wp->x;
	offy = y - wp->y;

/*printf("pid %d wid %d (oldpid %d) %d,%d\n", pwid, wid, wp->parent->id, pwp->unmapcount, wp->unmapcount);*/
	/* 
	 * Always unmap window, can't hurt if not mapped.
	 */
	wasmapped = (wp->unmapcount == 0);
	GsWpUnmapWindow(wp, GR_TRUE);

	for(mysibptr = &(wp->parent->children); *mysibptr != wp; 
		mysibptr = &((*mysibptr)->siblings))
			continue;
	*mysibptr = wp->siblings;
	wp->parent = pwp;
	wp->siblings = pwp->children;
	pwp->children = wp;
	OffsetWindow(wp, offx, offy);
#if 1	/* temp fix to bad mapcount reparenting code below*/
	GsWpMapWindow(wp, GR_FALSE);
#else
	/*
	 * If parent mapped and window was mapped, set unmapcount
	 * to 0 and remap window.
	 */
	if (!pwp->unmapcount && wasmapped) {
		SetUnmapCountTree(wp, 0, GR_FALSE);
		GsWpMapWindow(wp, GR_FALSE);
	} else {
		if (wasmapped)
			SetUnmapCountTree(wp, pwp->unmapcount, GR_FALSE);
		else SetUnmapCountTree(wp, pwp->unmapcount+1, GR_FALSE);
	}
#endif
}

static int nextgcid = 1000;
/*
 * Allocate a new GC with default parameters.
 * The GC is owned by the current client.
 */
GR_GC_ID 
GrNewGC(void)
{
	GR_GC	*gcp;

	gcp = (GR_GC *) malloc(sizeof(GR_GC));
	if (gcp == NULL) {
		GsError(GR_ERROR_MALLOC_FAILED, 0);
		return 0;
	}

	gcp->id = nextgcid++;
	gcp->mode = GR_MODE_COPY;
	gcp->regionid = 0;	/* no region*/
	gcp->xoff = 0;		/* no offset*/
	gcp->yoff = 0;
	gcp->fontid = 0;	/* 0 is default font*/
	gcp->foreground = WHITE;
	gcp->background = BLACK;
	gcp->usebackground = GR_TRUE;
	gcp->changed = GR_TRUE;
	gcp->owner = curclient;
	gcp->next = listgcp;

	listgcp = gcp;

	return gcp->id;
}

/*
 * Destroy an existing graphics context.
 */
void
GrDestroyGC(GR_GC_ID gc)
{
	GR_GC		*gcp;		/* graphics context */
	GR_GC		*prevgcp;	/* previous graphics context */

	gcp = GsFindGC(gc);
	if (gcp == NULL)
		return;

	if (gc == cachegcid) {
		cachegcid = 0;
		cachegcp = NULL;
	}
	if (gcp == curgcp)
		curgcp = NULL;

	if (listgcp == gcp)
		listgcp = gcp->next;
	else {
		prevgcp = listgcp;
		while (prevgcp->next != gcp)
			prevgcp = prevgcp->next;

		prevgcp->next = gcp->next;
	}
	free(gcp);
}

/*
 * Allocate a new GC which is a copy of another one.
 * The GC is owned by the current client.
 */
GR_GC_ID 
GrCopyGC(GR_GC_ID gc)
{
	GR_GC		*oldgcp;	/* old graphics context */
	GR_GC		*gcp;		/* new graphics context */

	oldgcp = GsFindGC(gc);
	if (oldgcp == NULL)
		return 0;

	gcp = (GR_GC *) malloc(sizeof(GR_GC));
	if (gcp == NULL) {
		GsError(GR_ERROR_MALLOC_FAILED, 0);
		return 0;
	}

	/*
	 * Copy all the old gcp values into the new one, except allocate
	 * a new id for it and link it into the list of GCs.
	 */
	*gcp = *oldgcp;
	gcp->id = nextgcid++;
	gcp->changed = GR_TRUE;
	gcp->owner = curclient;
	gcp->next = listgcp;
	listgcp = gcp;

	return gcp->id;
}

/*
 * Return information about the specified graphics context.
 */
void 
GrGetGCInfo(GR_GC_ID gcid, GR_GC_INFO *gcip)
{
	GR_GC		*gcp;

	/*
	 * Find the GC manually so that an error is not generated.
	 */
	for (gcp = listgcp; gcp && (gcp->id != gcid); gcp = gcp->next)
		continue;

	if (gcp == NULL) {
		memset(gcip, 0, sizeof(GR_GC_INFO));
		return;
	}

	gcip->gcid = gcid;
	gcip->mode = gcp->mode;
	gcip->region = gcp->regionid;
	gcip->xoff = gcp->xoff;
	gcip->yoff = gcp->yoff;
	gcip->font = gcp->fontid;
	gcip->foreground = gcp->foreground;
	gcip->background = gcp->background;
	gcip->usebackground = gcp->usebackground;
}

static int nextregionid = 1000;
/*
 * Allocate a new REGION with default parameters.
 * The REGION is owned by the current client.
 */
GR_REGION_ID
GrNewRegion(void)
{
	GR_REGION *regionp;
           
	regionp = (GR_REGION *) malloc(sizeof(GR_REGION));
	if (regionp == NULL) {
		GsError(GR_ERROR_MALLOC_FAILED, 0);
		return 0;
	}
	
	regionp->rgn = GdAllocRegion();
	regionp->id = nextregionid++;
	regionp->owner = curclient;
	regionp->next = listregionp;

	listregionp = regionp;
	return regionp->id;
}

/*
 * Allocate a new region from a set of points interpreted as a polygon.
 * The REGION is owned by the current client.
 */
GR_REGION_ID
GrNewPolygonRegion(int mode, GR_COUNT count, GR_POINT *points)
{
#if POLYREGIONS
	GR_REGION *regionp;
           
	regionp = (GR_REGION *) malloc(sizeof(GR_REGION));
	if (regionp == NULL) {
		GsError(GR_ERROR_MALLOC_FAILED, 0);
		return 0;
	}
	
	regionp->rgn = GdAllocPolygonRegion(points, count, mode);
	regionp->id = nextregionid++;
	regionp->owner = curclient;
	regionp->next = listregionp;

	listregionp = regionp;
	return regionp->id;
#else
	return 0;
#endif
}

/*
 * Destroy an existing region.
 */
void
GrDestroyRegion(GR_REGION_ID region)
{
	GR_REGION	*regionp;	/* region */
	GR_REGION	*prevregionp;	/* previous region */

	regionp = GsFindRegion(region);
	if (regionp == NULL)
		return;

	if (listregionp == regionp)
		listregionp = regionp->next;
	else {
		prevregionp = listregionp;
		while (prevregionp->next != regionp)
			prevregionp = prevregionp->next;

		prevregionp->next = regionp->next;
	}
	GdDestroyRegion(regionp->rgn);
	free(regionp);
}

/*
 * Updates the region from a union of the specified rectangle
 * and the original region.
 */
void
GrUnionRectWithRegion(GR_REGION_ID region, GR_RECT *rect)
{
	GR_REGION	*regionp;
	MWRECT		rc;
	
	regionp = GsFindRegion(region);
	if (regionp) {
		/* convert Nano-X rect to MW rect*/
		rc.left = rect->x;
		rc.top = rect->y;
		rc.right = rect->x + rect->width;
		rc.bottom = rect->y + rect->height;
		GdUnionRectWithRegion(&rc, regionp->rgn);	
	}
}

/*
 * Updates the region from a union of two regions.
 */ 
void
GrUnionRegion(GR_REGION_ID dst_rgn, GR_REGION_ID src_rgn1,
	GR_REGION_ID src_rgn2)
{
	GR_REGION	*regionp;
	GR_REGION	*srcregionp1;
	GR_REGION	*srcregionp2;
	
	regionp = GsFindRegion(dst_rgn);
	if (regionp == NULL)
		return;
	
	srcregionp1 = GsFindRegion(src_rgn1);
	if (srcregionp1 == NULL)
		return;
	
	srcregionp2 = GsFindRegion(src_rgn2);
	if (srcregionp2 == NULL)
		return;
	
	GdUnionRegion(regionp->rgn, srcregionp1->rgn, srcregionp2->rgn);
}

/*
 * Updates the region by subtracting a region from another.
 */ 
void
GrSubtractRegion(GR_REGION_ID dst_rgn, GR_REGION_ID src_rgn1,
	GR_REGION_ID src_rgn2)
{
	GR_REGION	*regionp;
	GR_REGION	*srcregionp1;
	GR_REGION	*srcregionp2;
	
	regionp = GsFindRegion(dst_rgn);
	if (regionp == NULL)
		return;
	
	srcregionp1 = GsFindRegion(src_rgn1);
	if (srcregionp1 == NULL)
		return;
	
	srcregionp2 = GsFindRegion(src_rgn2);
	if (srcregionp2 == NULL)
		return;
	
	GdSubtractRegion(regionp->rgn, srcregionp1->rgn, srcregionp2->rgn);
}

/*
 * Updates the region to the difference of two regions.
 */ 
void
GrXorRegion(GR_REGION_ID dst_rgn, GR_REGION_ID src_rgn1,
	GR_REGION_ID src_rgn2)
{
	GR_REGION	*regionp;
	GR_REGION	*srcregionp1;
	GR_REGION	*srcregionp2;
	
	regionp = GsFindRegion(dst_rgn);
	if (regionp == NULL)
		return;
	
	srcregionp1 = GsFindRegion(src_rgn1);
	if (srcregionp1 == NULL)
		return;
	
	srcregionp2 = GsFindRegion(src_rgn2);
	if (srcregionp2 == NULL)
		return;
	
	GdXorRegion(regionp->rgn, srcregionp1->rgn, srcregionp2->rgn);
}

/*
 * Updates the region from a intersection of two regions.
 */ 
void
GrIntersectRegion(GR_REGION_ID dst_rgn, GR_REGION_ID src_rgn1,
	GR_REGION_ID src_rgn2)
{
	GR_REGION	*regionp;
	GR_REGION	*srcregionp1;
	GR_REGION	*srcregionp2;
	
	regionp = GsFindRegion(dst_rgn);
	if (regionp == NULL)
		return;
	
	srcregionp1 = GsFindRegion(src_rgn1);
	if (srcregionp1 == NULL)
		return;
	
	srcregionp2 = GsFindRegion(src_rgn2);
	if (srcregionp2 == NULL)
		return;
	
	GdIntersectRegion(regionp->rgn, srcregionp1->rgn, srcregionp2->rgn);
}

/*
 * Sets the clip-mask in the GC to the specified region.
 */
void
GrSetGCRegion(GR_GC_ID gc, GR_REGION_ID region)
{
	GR_GC		*gcp;
	
	gcp = GsFindGC(gc);
	if(gcp == NULL)
		return;
	
	gcp->regionid = region;
	gcp->changed = GR_TRUE;
}

/*
 * Set the x,y origin of user clip region in GC.
 */
void
GrSetGCClipOrigin(GR_GC_ID gc, int xoff, int yoff)
{
	GR_GC		*gcp;

	gcp = GsFindGC(gc);
	if(gcp == NULL)
		return;

	gcp->xoff = xoff;
	gcp->yoff = yoff;
	gcp->changed = GR_TRUE;
}

/*
 * Determines whether a specified point resides in a region.
 */ 
GR_BOOL
GrPointInRegion(GR_REGION_ID region, GR_COORD x, GR_COORD y)
{
	GR_REGION	*regionp;
	
	regionp =  GsFindRegion(region);
	if (regionp == NULL)
		return GR_FALSE;
	
	return GdPtInRegion(regionp->rgn, x, y);
}

/*
 * Determines whether a specified rectangle at least partly resides
 * in a region.
 */ 
int
GrRectInRegion(GR_REGION_ID region, GR_COORD x, GR_COORD y, GR_COORD w,
	GR_COORD h)
{
	GR_REGION	*regionp;
	MWRECT		rect;
	
	regionp =  GsFindRegion(region);
	if (regionp == NULL)
		return MWRECT_OUT;
	
	rect.left = x;
	rect.top = y;
	rect.right = x + w;
	rect.bottom = y + h;
	return GdRectInRegion(regionp->rgn, &rect);
}

/*
 * Return GR_TRUE if a region is empty.
 */ 
GR_BOOL
GrEmptyRegion(GR_REGION_ID region)
{
	GR_REGION	*regionp;
	
	regionp =  GsFindRegion(region);
	if (regionp == NULL)
		return GR_TRUE;
	
	return GdEmptyRegion(regionp->rgn);
}

/*
 * Return GR_TRUE if two regions are identical.
 */ 
GR_BOOL
GrEqualRegion(GR_REGION_ID rgn1, GR_REGION_ID rgn2)
{
	GR_REGION	*prgn1;
	GR_REGION	*prgn2;
	
	prgn1 = GsFindRegion(rgn1);
	prgn2 = GsFindRegion(rgn2);

	if (!prgn1 && !prgn2)
		return GR_TRUE;
	if (!prgn1 || !prgn2)
		return GR_FALSE;
	
	return GdEqualRegion(prgn1->rgn, prgn2->rgn);
}

/*
 * Offset a region by dx, dy.
 */ 
void
GrOffsetRegion(GR_REGION_ID region, GR_SIZE dx, GR_SIZE dy)
{
	GR_REGION	*regionp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -