コード例 #1
0
ファイル: wingdi.c プロジェクト: EPiCS/reconos_v2
BOOL WINAPI
DeleteObject(HGDIOBJ hObject)
{
	if(!hObject || hObject->hdr.stockobj)
		return FALSE;
	if(hObject->hdr.type == OBJ_FONT)
		GdDestroyFont(((MWFONTOBJ *)hObject)->pfont);
	if(hObject->hdr.type == OBJ_REGION)
		GdDestroyRegion(((MWRGNOBJ *)hObject)->rgn);
	GdItemFree(hObject);
	return TRUE;
}
コード例 #2
0
ファイル: scr_mem.c プロジェクト: ghaerr/microwindows
/* close framebuffer*/
static void
fb_close(PSD psd)
{
	if (fb >= 0)
		close(fb);
	fb = -1;

	if ((psd->flags & PSF_ADDRMALLOC) && psd->addr)
		free (psd->addr);
	psd->addr = NULL;

 	if (fb_updateregion)
  		GdDestroyRegion(fb_updateregion);
	fb_updateregion = NULL;
}
コード例 #3
0
ファイル: winrgn.c プロジェクト: ghaerr/microwindows
HRGN WINAPI
CreatePolygonRgn(const POINT *points, INT count, INT mode)
{
#if POLYREGIONS
	HRGN		hrgn;
    	MWRGNOBJ * 	obj;
	MWCLIPREGION *	rgn;

    	if (!(hrgn = REGION_CreateRegion()))
		return NULL;
    	obj = (MWRGNOBJ *)GDI_GetObjPtr(hrgn, OBJ_REGION);
	if (!obj)
		return NULL;

	rgn = GdAllocPolygonRegion((POINT *)points, count, mode);
	if (!rgn)
		return hrgn;
	GdDestroyRegion(obj->rgn);
	obj->rgn = rgn;
	return hrgn;
#endif
}
コード例 #4
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;
}
コード例 #5
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);
}
コード例 #6
0
ファイル: srvutil.c プロジェクト: ghaerr/microwindows
/*
 * Destroy the specified window, and all of its children.
 * This is a recursive routine.
 */
void
GsDestroyWindow(GR_WINDOW *wp)
{
	GR_WINDOW	*prevwp;	/* previous window pointer */
	GR_EVENT_CLIENT	*ecp;		/* selections for window */
	GR_WINDOW_ID	oldwid;		/* old selection owner */
	GR_GRABBED_KEY *keygrab;
	GR_GRABBED_KEY **keygrab_prev_next;

	if (wp == rootwp) {
		GsError(GR_ERROR_ILLEGAL_ON_ROOT_WINDOW, wp->id);
		return;
	}

	/* Disable selection if this window is the owner */
	if(selection_owner.wid == wp->id) {
		oldwid = selection_owner.wid;
		selection_owner.wid = 0;
		if(selection_owner.typelist)
			free(selection_owner.typelist);
		selection_owner.typelist = NULL;
		GsDeliverSelectionChangedEvent(oldwid, 0);
	}

	/*
	 * Unmap the window first.
	 */
	if (wp->realized)
		GsUnrealizeWindow(wp, GR_FALSE);

	/* send destroy update event*/
	GsDeliverUpdateEvent(wp, GR_UPDATE_DESTROY, wp->x, wp->y,
		wp->width, wp->height);

	/*
	 * Destroy all children.
	 */
	while (wp->children)
		GsDestroyWindow(wp->children);

	/*
	 * Free all client selection structures.
	 */
	while (wp->eventclients) {
		ecp = wp->eventclients;
		wp->eventclients = ecp->next;
DPRINTF("FREE 1 %lx\n", (long)ecp);			// FIXME
		free(ecp);
	}

	/*
	 * Remove this window from the child list of its parent.
	 */
	prevwp = wp->parent->children;
	if (prevwp == wp)
		wp->parent->children = wp->siblings;
	else {
		while (prevwp->siblings != wp)
			prevwp = prevwp->siblings;
		prevwp->siblings = wp->siblings;
	}
	wp->siblings = NULL;

	/*
	 * Remove this window from the complete list of windows.
	 */
	prevwp = listwp;
	if (prevwp == wp)
		listwp = wp->next;
	else {
		while (prevwp->next != wp)
			prevwp = prevwp->next;
		prevwp->next = wp->next;
	}
	wp->next = NULL;

	/*
	 * Forget various information if they related to this window.
	 * Then finally free the structure.
	 */
	if (wp == clipwp)
		clipwp = NULL;
	if (wp == grabbuttonwp)
		grabbuttonwp = NULL;
	if (wp == cachewp) {
		cachewindowid = 0;
		cachewp = NULL;
	}
	if (wp == focuswp) {
		/* don't revert to mouse enter/leave focus if fixed*/
		/*focusfixed = GR_FALSE;*/
		focuswp = rootwp;
	}

	GsCheckMouseWindow();

	/*
	 * Free title, pixmaps and clipregions associated with window.
	 */
	if (wp->title)
		free(wp->title);
	if (wp->bgpixmap)
		GsDestroyPixmap(wp->bgpixmap);
	if (wp->buffer)
		GsDestroyPixmap(wp->buffer);
#if DYNAMICREGIONS
	if (wp->clipregion)
		GdDestroyRegion(wp->clipregion);
#endif

	/* Remove any grabbed keys for this window. */
	keygrab_prev_next = &list_grabbed_keys;
	keygrab           =  list_grabbed_keys;
	while (keygrab != NULL) {
		if (keygrab->wid == wp->id){
			/* Delete keygrab. */
			*keygrab_prev_next = keygrab->next;
			free(keygrab);
			keygrab = *keygrab_prev_next;
		} else {
			keygrab_prev_next = &keygrab->next;
			keygrab           =  keygrab->next;
		}
	}

	free(wp);
}
コード例 #7
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;
}
コード例 #8
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);
}
コード例 #9
0
ファイル: winuser.c プロジェクト: alex-sever-h/microwin
/*
 * Destroy the specified window, and all of its children.
 * This is a recursive routine.
 */
void
MwDestroyWindow(HWND hwnd,BOOL bSendMsg)
{
	HWND	wp = hwnd;
	HWND	prevwp;
	PMWLIST	p;
	PMSG	pmsg;

	if (wp == rootwp || !IsWindow (hwnd))
		return;

	/*
	 * Unmap the window.
	 */
	if (wp->unmapcount == 0)
		MwHideWindow(wp, FALSE, FALSE);

	if(bSendMsg)
		SendMessage(hwnd, WM_DESTROY, 0, 0L);

	/*
	 * Remove from timers
	 */
	MwRemoveWndFromTimers(hwnd);

	/*
	 * Remove hotkeys
	 */
	MwRemoveWndFromHotkeys(hwnd);

	/*
	 * Disable all sendmessages to this window.
	 */
	wp->lpfnWndProc = NULL;

	/*
	 * Destroy all children, sending WM_DESTROY messages.
	 */
	while (wp->children)
		MwDestroyWindow(wp->children, bSendMsg);

	wp->pClass = NULL;

	/*
	 * Free any cursor associated with the window.
	 */
	if (wp->cursor->usecount-- == 1) {
		free(wp->cursor);
		wp->cursor = NULL;
	}

	/*
	 * Remove this window from the child list of its parent.
	 */
	prevwp = wp->parent->children;
	if (prevwp == wp)
		wp->parent->children = wp->siblings;
	else {
		while (prevwp && prevwp->siblings != wp)
			prevwp = prevwp->siblings;
		if (prevwp) prevwp->siblings = wp->siblings;
	}
	wp->siblings = NULL;

	/*
	 * Remove this window from the complete list of windows.
	 */
	prevwp = listwp;
	if (prevwp == wp)
		listwp = wp->next;
	else {
		while (prevwp->next && prevwp->next != wp)
			prevwp = prevwp->next;
		prevwp->next = wp->next;
	}
	wp->next = NULL;

	/*
	 * Forget various information related to this window.
	 * Then finally free the structure.
	 */

	/* Remove all messages from msg queue for this window*/
	for(p=mwMsgHead.head; p; ) {
		pmsg = GdItemAddr(p, MSG, link);
		if(pmsg->hwnd == wp) {
			p = p->next;
			GdListRemove(&mwMsgHead, &pmsg->link);
			GdItemFree(pmsg);
		} else
			p = p->next;
	}

	/*
	 * Remove all properties from this window.
	 */
	for(p=hwnd->props.head; p; ) {
		MWPROP  *pProp = GdItemAddr(p, MWPROP, link);
		p = p->next;
		GdListRemove (&hwnd->props, &pProp->link);
		GdItemFree (pProp);
	}

	/* FIXME: destroy hdc's relating to window?*/

	if (wp == capturewp) {
		capturewp = NULL;
		MwCheckMouseWindow();
	}

	if (wp == MwGetTopWindow(focuswp))
		SetFocus(rootwp->children? rootwp->children: rootwp);

	/* destroy private DC*/
	if(wp->owndc) {
		HDC hdc = wp->owndc;
		wp->owndc = NULL;	/* force destroy with ReleaseDC*/
		ReleaseDC(wp, hdc);
	}

	if (wp->szTitle) {
		free(wp->szTitle);
		wp->szTitle = NULL;
	}

#if UPDATEREGIONS
	if (wp->update) {
		GdDestroyRegion(wp->update);
		wp->update = NULL;
	}
#endif

	GdItemFree(wp);
}
コード例 #10
0
ファイル: devrgn2.c プロジェクト: lepton-distribution/lepton
/*
 *           GdAllocPolyPolygonRegion
 */
MWCLIPREGION *
GdAllocPolyPolygonRegion(MWPOINT *points, int *count, int nbpolygons, int mode)
{
    MWCLIPREGION *rgn;
    EdgeTableEntry *pAET;   /* Active Edge Table       */
    int y;                  /* current scanline        */
    int iPts = 0;           /* number of pts in buffer */
    EdgeTableEntry *pWETE;  /* Winding Edge Table Entry*/
    ScanLineList *pSLL;     /* current scanLineList    */
    MWPOINT *pts;           /* output buffer           */
    EdgeTableEntry *pPrevAET;        /* ptr to previous AET     */
    EdgeTable ET;                    /* header node for ET      */
    EdgeTableEntry AET;              /* header node for AET     */
    EdgeTableEntry *pETEs;           /* EdgeTableEntries pool   */
    ScanLineListBlock SLLBlock;      /* header for scanlinelist */
    int fixWAET = FALSE;
    POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers    */
    POINTBLOCK *tmpPtBlock;
    int numFullPtBlocks = 0;
    int poly, total;

    if(!(rgn = GdAllocRegion()))
        return NULL;

    /* special case a rectangle */

    if (((nbpolygons == 1) && ((*count == 4) ||
       ((*count == 5) && (points[4].x == points[0].x)
        && (points[4].y == points[0].y)))) &&
        (((points[0].y == points[1].y) &&
          (points[1].x == points[2].x) &&
          (points[2].y == points[3].y) &&
          (points[3].x == points[0].x)) ||
         ((points[0].x == points[1].x) &&
          (points[1].y == points[2].y) &&
          (points[2].x == points[3].x) &&
          (points[3].y == points[0].y))))
    {
        GdSetRectRegion( rgn,
	    MWMIN(points[0].x, points[2].x), MWMIN(points[0].y, points[2].y),
	    MWMAX(points[0].x, points[2].x), MWMAX(points[0].y, points[2].y) );
        return rgn;
    }

    for(poly = total = 0; poly < nbpolygons; poly++)
        total += count[poly];
    if (! (pETEs = malloc( sizeof(EdgeTableEntry) * total )))
    {
        GdDestroyRegion( rgn );
        return 0;
    }
    pts = FirstPtBlock.pts;
    REGION_CreateETandAET(count, nbpolygons, points, &ET, &AET,
        pETEs, &SLLBlock);
    pSLL = ET.scanlines.next;
    curPtBlock = &FirstPtBlock;

    if (mode != MWPOLY_WINDING) {
        /*
         *  for each scanline
         */
        for (y = ET.ymin; y < ET.ymax; y++) {
            /*
             *  Add a new edge to the active edge table when we
             *  get to the next edge.
             */
            if (pSLL != NULL && y == pSLL->scanline) {
                REGION_loadAET(&AET, pSLL->edgelist);
                pSLL = pSLL->next;
            }
            pPrevAET = &AET;
            pAET = AET.next;

            /*
             *  for each active edge
             */
            while (pAET) {
                pts->x = pAET->bres.minor_axis,  pts->y = y;
                pts++, iPts++;

                /*
                 *  send out the buffer
                 */
                if (iPts == NUMPTSTOBUFFER) {
                    tmpPtBlock = malloc( sizeof(POINTBLOCK));
                    if(!tmpPtBlock) {
                        return 0;
                    }
                    curPtBlock->next = tmpPtBlock;
                    curPtBlock = tmpPtBlock;
                    pts = curPtBlock->pts;
                    numFullPtBlocks++;
                    iPts = 0;
                }
                EVALUATEEDGEEVENODD(pAET, pPrevAET, y);

            }
            REGION_InsertionSort(&AET);
        }
    }
    else {
        /*
         *  for each scanline
         */
        for (y = ET.ymin; y < ET.ymax; y++) {
            /*
             *  Add a new edge to the active edge table when we
             *  get to the next edge.
             */
            if (pSLL != NULL && y == pSLL->scanline) {
                REGION_loadAET(&AET, pSLL->edgelist);
                REGION_computeWAET(&AET);
                pSLL = pSLL->next;
            }
            pPrevAET = &AET;
            pAET = AET.next;
            pWETE = pAET;

            /*
             *  for each active edge
             */
            while (pAET) {
                /*
                 *  add to the buffer only those edges that
                 *  are in the Winding active edge table.
                 */
                if (pWETE == pAET) {
                    pts->x = pAET->bres.minor_axis,  pts->y = y;
                    pts++, iPts++;

                    /*
                     *  send out the buffer
                     */
                    if (iPts == NUMPTSTOBUFFER) {
                        tmpPtBlock = malloc( sizeof(POINTBLOCK) );
                        if(!tmpPtBlock) {
                            return 0;
                        }
                        curPtBlock->next = tmpPtBlock;
                        curPtBlock = tmpPtBlock;
                        pts = curPtBlock->pts;
                        numFullPtBlocks++;    iPts = 0;
                    }
                    pWETE = pWETE->nextWETE;
                }
                EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
            }

            /*
             *  recompute the winding active edge table if
             *  we just resorted or have exited an edge.
             */
            if (REGION_InsertionSort(&AET) || fixWAET) {
                REGION_computeWAET(&AET);
                fixWAET = FALSE;
            }
        }
    }
    REGION_FreeStorage(SLLBlock.next);
    REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, rgn);
    for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
        tmpPtBlock = curPtBlock->next;
        free( curPtBlock );
        curPtBlock = tmpPtBlock;
    }
    free( pETEs );
    return rgn;
}
コード例 #11
0
ファイル: devclip2.c プロジェクト: Kvasshtain/uos-embedded
/**
 * Set a clip region for future drawing actions.
 * Each pixel will be drawn only if lies in one or more of the contained
 * clip rectangles.  All clip rectangles are modified
 * if necessary to lie within the device area.  Call only after device
 * has been initialized.
 *
 * @param psd Drawing surface.
 * @param reg New clipping region.
 */
void
GdSetClipRegion(PSD psd, MWCLIPREGION *reg)
{
  if(clipregion)
  	GdDestroyRegion(clipregion);

  if(!reg)
	  reg = GdAllocRegion();

  clipregion = reg;


#if 0
  MWRECT	rc;
  /* Copy the clip table to our own static array, modifying each
   * rectangle as necesary to fit within the device area.  If the clip
   * rectangle lies entirely outside of the device area, then skip it.
   */
  while (count-- > 0) {
	MWCLIPRECT cr;
	MWCLIPRECT *rp = &cr;

	*rp = *table++;
	if (rp->x < 0) {
		rp->width += rp->x;
		rp->x = 0;
	}
	if (rp->y < 0) {
		rp->height += rp->y;
		rp->y = 0;
	}
	if ((rp->x >= psd->xvirtres) || (rp->width <= 0) ||
	    (rp->y >= psd->yvirtres) || (rp->height <= 0))
		continue;
	if (rp->x + rp->width > psd->xvirtres)
		rp->width = psd->xvirtres - rp->x;
	if (rp->y + rp->height > psd->yvirtres)
		rp->height = psd->yvirtres - rp->y;
	rc.left = rp->x;
	rc.top = rp->y;
	rc.right = rp->x+rp->width;
	rc.bottom = rp->y+rp->height;
	GdUnionRectWithRegion(&rc, clipregion);
  }
#endif

  /* If there were no surviving clip rectangles, then set the clip
   * cache to prevent all drawing.
   */
  if (clipregion->numRects == 0) {
	clipminx = MIN_MWCOORD;
	clipminy = MIN_MWCOORD;
	clipmaxx = MAX_MWCOORD;
	clipmaxy = MAX_MWCOORD;
	clipresult = FALSE;
	return;
  }

  /* There was at least one valid clip rectangle. Default the clip
   * cache to be the first clip rectangle.
   */
  clipminx = clipregion->rects[0].left;
  clipminy = clipregion->rects[0].top;
  clipmaxx = clipregion->rects[0].right - 1;
  clipmaxy = clipregion->rects[0].bottom - 1;
  clipresult = TRUE;
}