Пример #1
0
/* init buffered windows by allocating pixmap buffer and clearing background*/
void
GsInitWindowBuffer(GR_WINDOW *wp, GR_SIZE width, GR_SIZE height)
{
	/* create same size RGBA pixmap for buffer*/
	GR_WINDOW_ID id;
	
	/* check if buffer size changed*/
	if (wp->buffer) {
		if (wp->width == width && wp->height == height)
			return;
		GsDestroyPixmap(wp->buffer);
	}

	id = GsNewPixmap(width, height, MWIF_RGBA8888, NULL);
	wp->buffer = GsFindPixmap(id);
	if (!wp->buffer) {
		wp->props &= ~(GR_WM_PROPS_BUFFERED | GR_WM_PROPS_DRAWING_DONE);
		return;
	}

	/* mark buffer as not ready for display*/
	wp->props &= ~GR_WM_PROPS_DRAWING_DONE;

	/* clear buffer to background color*/
	if (!(wp->props & GR_WM_PROPS_NOBACKGROUND)) {
		GR_PIXMAP *pp = wp->buffer;

		/* clip to pixmap boundaries*/
#if DYNAMICREGIONS
		GdSetClipRegion(pp->psd, GdAllocRectRegion(0, 0, pp->psd->xvirtres, pp->psd->yvirtres));
#else
		MWCLIPRECT	cliprect;
		cliprect.x = 0;
		cliprect.y = 0;
		cliprect.width = pp->psd->xvirtres;
		cliprect.height = pp->psd->yvirtres;
		GdSetClipRects(pp->psd, 1, &cliprect);
#endif
		clipwp = NULL;			/* reset clip cache for next window draw*/
		curgcp = NULL;			/* invalidate gc cache since we're changing color and mode*/
		GdSetFillMode(GR_FILL_SOLID);
		GdSetMode(GR_MODE_COPY);
		GdSetForegroundColor(pp->psd, wp->background);

		GdFillRect(pp->psd, 0, 0, pp->width, pp->height);
	}
}
Пример #2
0
/* 
 * Setup clip region from device context's associated window or bitmap.
 * Memory DC's are always associated with the desktop window, and are
 * always visible.  Return the DC's hwnd if window is visible.
 */
HWND
MwPrepareDC(HDC hdc)
{
	HWND	hwnd;

	if(!hdc || !hdc->hwnd)
		return NULL;

	hwnd = hdc->hwnd;
	if (hwnd->unmapcount)
		return NULL;

	/*
	 * If the window is not the currently clipped one, then
	 * make it the current one and define its clip rectangles.
	 */
	if(hdc != cliphdc) {
		/* clip memory dc's to the bitmap size*/
		if(hdc->psd->flags&PSF_MEMORY) {
#if DYNAMICREGIONS
			GdSetClipRegion(hdc->psd,
				GdAllocRectRegion(0, 0, hdc->psd->xvirtres,
					hdc->psd->yvirtres));
#else
			static MWCLIPRECT crc = {0, 0, 0, 0};

			crc.width = hdc->psd->xvirtres;
			crc.height = hdc->psd->yvirtres;
			GdSetClipRects(hdc->psd, 1, &crc);
#endif
		} else MwSetClipWindow(hdc);
		cliphdc = hdc;
	}

	return hwnd;
}
Пример #3
0
/*
 * 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;
}
Пример #4
0
/*
 * 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	*pwp;		/* parent window */
	GR_WINDOW	*sibwp;		/* sibling windows */
	MWCLIPRECT	*clip;		/* first clip rectangle */
	GR_COUNT	count;		/* number of clip rectangles */
	GR_COUNT	newcount;	/* number of new rectangles */
	GR_COUNT	i;		/* current index */
	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_BOOL		toomany;	/* TRUE if too many clip rects */
	MWCLIPRECT	cliprects[MAX_CLIPRECTS];	/* clip rectangles */

	if (!wp->realized || !wp->output || (wp == clipwp))
		return;

	clipwp = wp;

	/*
	 * Start with the rectangle for the complete window.
	 * We will then cut pieces out of it as needed.
	 */
	count = 1;
	clip = cliprects;
	clip->x = wp->x;
	clip->y = wp->y;
	clip->width = wp->width;
	clip->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 - clip->x;
		if (diff > 0) {
			clip->width -= diff;
			clip->x = pwp->x;
		}

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

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

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

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

	/*
	 * 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.
 	 */
	toomany = GR_FALSE;
	pwp = wp;
/*while (pwp != rootwp) {*/
	while (pwp != NULL) {
		wp = pwp;
		pwp = wp->parent;

		if(!pwp) {
			/* We're clipping the root window*/
			sibwp = rootwp->children;
			wp = NULL;
		} else
			sibwp = pwp->children;

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

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

			newcount = count;
			for (i = 0; i < count; i++) {
				if (newcount > MAX_CLIPRECTS - 3) {
					toomany = GR_TRUE;
					break;
				}
				newcount += GsSplitClipRect(&cliprects[i],
					&cliprects[newcount],
					minx, miny, maxx, maxy);
			}
			count = newcount;
		}
if(pwp == rootwp)
break;
	}

	if (toomany) {
		GsError(GR_ERROR_TOO_MUCH_CLIPPING, wp->id);
		clip->x = 0;
		clip->y = 0;
		clip->width = -1;
		clip->height = -1;
		count = 1;
	}

	/*
	 * Set the clip rectangles.
	 */
	GdSetClipRects(clipwp->psd, count, cliprects);
}
Пример #5
0
/*
 * 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;
}
Пример #6
0
/*
 * Open low level graphics driver
 */
PSD
GdOpenScreen(void)
{
	PSD			psd;
	MWPALENTRY *		stdpal;
	MWSCREENINFO		sinfo;	    

	psd = scrdev.Open(&scrdev);
	if (!psd)
		return NULL;
	GdGetScreenInfo(psd, &sinfo);
	gr_pixtype = sinfo.pixtype;
	gr_ncolors = sinfo.ncolors;

	/* assume no user changable palette entries*/
	gr_firstuserpalentry = (int)psd->ncolors;

	/* set palette according to system colors and devpalX.c*/
	switch((int)psd->ncolors) {

#if !defined(NOSTDPAL1) /* don't require stdpal1 if not needed */
	case 2:		/* 1bpp*/
	{
		extern MWPALENTRY	mwstdpal1[2];
		stdpal = mwstdpal1;
	}
	break;
#endif

#if !defined(NOSTDPAL2) /* don't require stdpal2 if not needed */
	case 4:		/* 2bpp*/
	{
		extern MWPALENTRY	mwstdpal2[4];
		stdpal = mwstdpal2;
	}
	break;
#endif

#if !defined(NOSTDPAL4)
	/* don't require stdpal4 if not needed */
	case 8:		/* 3bpp - not fully supported*/
	case 16:	/* 4bpp*/
	{
		extern MWPALENTRY	mwstdpal4[16];
		stdpal = mwstdpal4;
	}
	break;
#endif

#if !defined(NOSTDPAL8) /* don't require large stdpal8 if not needed */
	case 256:	/* 8bpp*/
	{
		extern MWPALENTRY	mwstdpal8[256];
#if xxxALPHABLEND
		/* don't change uniform palette if alpha blending*/
		gr_firstuserpalentry = 256;
#else
		/* start after last system-reserved color*/
		gr_firstuserpalentry = FIRSTUSERPALENTRY;
#endif
		stdpal = mwstdpal8;
	} 
	break;
#endif	/* !defined(NOSTDPAL8)*/

	default:	/* truecolor*/
		/* no palette*/
		gr_firstuserpalentry = 0;
		stdpal = NULL;
	}

	/* reset next user palette entry, write hardware palette*/
	GdResetPalette();
	GdSetPalette(psd, 0, (int)psd->ncolors, stdpal);
#if xxxALPHABLEND
	/* one-time create alpha lookup table for 8bpp systems (takes ~1 sec)*/
	if(psd->ncolors == 256)
		init_alpha_lookup();
#endif

#if !NOFONTSORCLIPPING
	/* init local vars*/
	GdSetMode(MWMODE_COPY);
	GdSetForeground(GdFindColor(MWRGB(255, 255, 255)));	/* WHITE*/
	GdSetBackground(GdFindColor(MWRGB(0, 0, 0)));		/* BLACK*/
	GdSetUseBackground(TRUE);
	GdSetFont(GdCreateFont(psd, MWFONT_SYSTEM_VAR, 0, NULL));
#if DYNAMICREGIONS
	GdSetClipRegion(psd, 
		GdAllocRectRegion(0, 0, psd->xvirtres, psd->yvirtres));
#else
	GdSetClipRects(psd, 0, NULL);
#endif /* DYNAMICREGIONS*/
#endif /* NOFONTSORCLIPPING*/

	/* fill black (actually fill to first palette entry or truecolor 0*/
	psd->FillRect(psd, 0, 0, psd->xvirtres-1, psd->yvirtres-1, 0);
	return psd;
}
Пример #7
0
/* 
 * Setup clip region from device context's associated window or bitmap.
 * Memory DC's are always associated with the desktop window, and are
 * always visible.  Return the DC's hwnd if window is visible.
 */
HWND
MwPrepareDC(HDC hdc)
{
	HWND	hwnd;

	if(!hdc || !hdc->hwnd)
		return NULL;

	hwnd = hdc->hwnd;
	if (hwnd->unmapcount)
		return NULL;

	/*
	 * If the window is not the currently clipped one, then
	 * make it the current one and define its clip rectangles.
	 */
	if(hdc != cliphdc) {
		/* clip memory dc's to the bitmap size*/
		if(hdc->psd->flags&PSF_MEMORY) {
#if DYNAMICREGIONS
			/* If hdc has a clip region, use it! */
			if (hdc->region != NULL && hdc->region->rgn != NULL
			    && hdc->region->rgn->size != 0) {
				LPRECT rptr = &(hdc->region->rgn->extents);
				MWCOORD left, top;

				/* Bound left,top to 0,0 if they are negative
				 * to avoid an assertion later.
				 */
				left = (rptr->left <= 0) ? 0 : rptr->left;
				top = (rptr->top <= 0) ? 0 : rptr->top;
				GdSetClipRegion(hdc->psd,
					GdAllocRectRegion(rptr->left, rptr->top,
						rptr->right, rptr->bottom));
			} else {
				GdSetClipRegion(hdc->psd,
					GdAllocRectRegion(0, 0,
						hdc->psd->xvirtres, hdc->psd->yvirtres));
			}
#else
			static MWCLIPRECT crc = {0, 0, 0, 0};

			/* If hdc has a clip region, use it! */
			if (hdc->region != NULL && hdc->region->rgn != NULL
			    && hdc->region->rgn->size != 0) {
				LPRECT rptr = &(hdc->region->rgn->extents);

				/* Bound left,top to 0,0 if they are negative
				 * to avoid an assertion later.
				 */
				if (rptr->left > 0)
					crc.x = rptr->left;
				if (rptr->top > 0)
					crc.y = rptr->top;
				crc.width = rptr->right;
				crc.height = rptr->bottom;
			} else {
				crc.width = hdc->psd->xvirtres;
				crc.height = hdc->psd->yvirtres;
			}
			GdSetClipRects(hdc->psd, 1, &crc);
#endif
		} else MwSetClipWindow(hdc);
		cliphdc = hdc;
	}

	return hwnd;
}
Пример #8
0
/**
 * Open low level graphics driver.
 *
 * @return The screen drawing surface.
 */
PSD
GdOpenScreen(void)
{
	PSD			psd;
	MWPALENTRY *		stdpal;

	psd = scrdev.Open(&scrdev);
	if (!psd)
		return NULL;

	/* assume no user changable palette entries*/
	gr_firstuserpalentry = (int)psd->ncolors;

	/* set palette according to system colors and devpalX.c*/
	switch((int)psd->ncolors) {

#if !defined(NOSTDPAL1) /* don't require stdpal1 if not needed */
	case 2:		/* 1bpp*/
	{
		extern MWPALENTRY	mwstdpal1[2];
		stdpal = mwstdpal1;
	}
	break;
#endif

#if !defined(NOSTDPAL2) /* don't require stdpal2 if not needed */
	case 4:		/* 2bpp*/
	{
		extern MWPALENTRY	mwstdpal2[4];
		stdpal = mwstdpal2;
	}
	break;
#endif

#if !defined(NOSTDPAL4)
	/* don't require stdpal4 if not needed */
	case 8:		/* 3bpp - not fully supported*/
	case 16:	/* 4bpp*/
	{
		extern MWPALENTRY	mwstdpal4[16];
		stdpal = mwstdpal4;
	}
	break;
#endif

#if !defined(NOSTDPAL8) /* don't require large stdpal8 if not needed */
	case 256:	/* 8bpp*/
	{
		extern MWPALENTRY	mwstdpal8[256];
#if UNIFORMPALETTE
		/* don't change uniform palette if alpha blending*/
		gr_firstuserpalentry = 256;
#else
		/* start after last system-reserved color*/
		gr_firstuserpalentry = FIRSTUSERPALENTRY;
#endif
		stdpal = mwstdpal8;
	} 
	break;
#endif	/* !defined(NOSTDPAL8)*/

	default:	/* truecolor*/
		/* no palette*/
		gr_firstuserpalentry = 0;
		stdpal = NULL;
	}

	/* reset next user palette entry, write hardware palette*/
	GdResetPalette();
	GdSetPalette(psd, 0, (int)psd->ncolors, stdpal);

	/* init local vars*/
	GdSetMode(MWROP_COPY);
	GdSetFillMode(MWFILL_SOLID);  /* Set the fill mode to solid */

	GdSetForegroundColor(psd, MWRGB(255, 255, 255));	/* WHITE*/
	GdSetBackgroundColor(psd, MWRGB(0, 0, 0));		/* BLACK*/
	GdSetUseBackground(TRUE);
	/* select first builtin font (usually MWFONT_SYSTEM_VAR)*/
	//GdSetFont(GdCreateFont(psd, NULL, 0, 0, NULL));

	GdSetDash(0, 0);  /* No dashing to start */
	GdSetStippleBitmap(0,0,0);  /* No stipple to start */

#if !NOCLIPPING
#if DYNAMICREGIONS
	GdSetClipRegion(psd, GdAllocRectRegion(0, 0, psd->xvirtres, psd->yvirtres));
#else
	GdSetClipRects(psd, 0, NULL);
#endif /* DYNAMICREGIONS*/
#endif /* NOCLIPPING*/

	/* fill black (actually fill to first palette entry or truecolor 0*/
	psd->FillRect(psd, 0, 0, psd->xvirtres-1, psd->yvirtres-1, 0);
	return psd;
}