Example #1
0
/*
 *          Create a new empty region.
 */
static HRGN
REGION_CreateRegion(void)
{
    MWRGNOBJ *obj;
    
    obj = GdItemNew(MWRGNOBJ);
    if(!obj)
    	return NULL;
    obj->hdr.type = OBJ_REGION;
    obj->hdr.stockobj = FALSE;
    if(!(obj->rgn = GdAllocRegion())) {
	GdItemFree(obj);
	return NULL;
    }
    return (HRGN)obj;
}
Example #2
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;
}
Example #3
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.
 */
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);
}
Example #4
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;
}
Example #5
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	*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);
}
Example #6
0
/* init framebuffer*/
static PSD
fb_open(PSD psd)
{
	PSUBDRIVER subdriver;
	char *env;

	/* set statically in struct definition, may be overridden before calling fb_open*/
	//psd->xres = psd->xvirtres = SCREEN_WIDTH;
	//psd->yres = psd->yvirtres = SCREEN_HEIGHT;

	/* use pixel format to set bpp*/
	psd->pixtype = MWPIXEL_FORMAT;
	switch (psd->pixtype) {
	case MWPF_TRUECOLORARGB:
	case MWPF_TRUECOLORABGR:
	default:
		psd->bpp = 32;
		break;

	case MWPF_TRUECOLORRGB:
		psd->bpp = 24;
		break;

	case MWPF_TRUECOLOR565:
	case MWPF_TRUECOLOR555:
		psd->bpp = 16;
		break;

	case MWPF_TRUECOLOR332:
		psd->bpp = 8;
		break;

#if MWPIXEL_FORMAT == MWPF_PALETTE
	case MWPF_PALETTE:
		psd->bpp = SCREEN_DEPTH;
		break;
#endif
	}
	psd->planes = 1;

	/* set standard data format from bpp and pixtype*/
	psd->data_format = set_data_format(psd);

	/* Calculate the correct size and pitch from xres, yres and bpp*/
	GdCalcMemGCAlloc(psd, psd->xres, psd->yres, psd->planes, psd->bpp, &psd->size, &psd->pitch);

	psd->ncolors = (psd->bpp >= 24)? (1 << 24): (1 << psd->bpp);
	psd->flags = PSF_SCREEN;
	psd->portrait = MWPORTRAIT_NONE;

	/* select an fb subdriver matching our planes and bpp for backing store*/
	subdriver = select_fb_subdriver(psd);
	psd->orgsubdriver = subdriver;
	if (!subdriver)
		return NULL;

	/* set subdriver into screen driver*/
	set_subdriver(psd, subdriver);

#ifdef PATH_FRAMEBUFFER
	/* try opening framebuffer file for mmap*/
	if((env = getenv("FRAMEBUFFER")) == NULL)
		env = PATH_FRAMEBUFFER;
	fb = open(env, O_RDWR);
#endif
	if (fb >= 0) {
		/* mmap framebuffer into this address space*/
		psd->size = (psd->size + getpagesize() - 1) / getpagesize() * getpagesize();
		psd->addr = mmap(NULL, psd->size, PROT_READ|PROT_WRITE, MAP_SHARED, fb, 0);
		if (psd->addr == NULL || psd->addr == (unsigned char *)-1) {
			EPRINTF("Error mmaping shared framebuffer %s: %m\n", env);
			close(fb);
			return NULL;
		}
	} else {
		/* allocate framebuffer*/
		if ((psd->addr = malloc(psd->size)) == NULL)
			return NULL;
		psd->flags |= PSF_ADDRMALLOC;
	}

	/* allocate update region*/
	fb_updateregion = GdAllocRegion();

	return psd;	/* success*/
}
Example #7
0
/*
 * Initialize the graphics and mouse devices at startup.
 * Returns nonzero with a message printed if the initialization failed.
 */
int
MwInitialize(void)
{
	HWND		wp;		/* root window */
	PSD		psd;
	WNDCLASS	wc;
	int		fd;
	static MWCURSOR arrow = {	/* default arrow cursor*/
		16, 16,
		0,  0,
		RGB(255, 255, 255), RGB(0, 0, 0),
		{ 0xe000, 0x9800, 0x8600, 0x4180,
		  0x4060, 0x2018, 0x2004, 0x107c,
		  0x1020, 0x0910, 0x0988, 0x0544,
		  0x0522, 0x0211, 0x000a, 0x0004 },
		{ 0xe000, 0xf800, 0xfe00, 0x7f80,
		  0x7fe0, 0x3ff8, 0x3ffc, 0x1ffc,
		  0x1fe0, 0x0ff0, 0x0ff8, 0x077c,
		  0x073e, 0x021f, 0x000e, 0x0004 }
	};

	extern MWLISTHEAD mwClassHead;

#if (UNIX | DOS_DJGPP) && !_MINIX
	for (fd = 0; fd < FD_SETSIZE; fd++) {
		userregfd[fd].read = NULL;
		userregfd[fd].write = NULL;
		userregfd[fd].except = NULL;
		userregfd[fd].next = -1;
  	}
	userregfd_head = -1;
#endif
	/* catch terminate signal to restore tty state*/
	signal(SIGTERM, (void *)MwTerminate);

	startTicks = GetTickCount();

	if ((keyb_fd = GdOpenKeyboard()) == -1) {
		EPRINTF("Cannot initialise keyboard\n");
		return -1;
	}

	if ((psd = GdOpenScreen()) == NULL) {
		EPRINTF("Cannot initialise screen\n");
		GdCloseKeyboard();
		return -1;
	}

	if ((mouse_fd = GdOpenMouse()) == -1) {
		EPRINTF("Cannot initialise mouse\n");
		GdCloseScreen(psd);
		GdCloseKeyboard();
		return -1;
	}

#if ANIMATEPALETTE
	setfadelevel(psd, 0);
#endif
	/*
	 * Initialize the root window.
	 */
	wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
	wc.lpfnWndProc = (WNDPROC)DefWindowProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = 0;
	wc.hIcon = 0; /*LoadIcon(GetHInstance(), MAKEINTRESOURCE( 1));*/
	wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/
	wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));
	wc.lpszMenuName = NULL;
	wc.lpszClassName =  "DeskTop";
	RegisterClass( &wc);
	
	wp = GdItemNew(struct hwnd);
	if (!wp) {
		EPRINTF("No memory for root window\n");
		GdCloseMouse();
		GdCloseScreen(psd);
		GdCloseKeyboard();
		return -1;
	}
	/* remove the WS_CAPTION to have bare desktop window*/
	/*wp->style = WS_CLIPCHILDREN | WS_CAPTION | WS_VISIBLE;*/
	wp->style = WS_CLIPCHILDREN | WS_VISIBLE;
	wp->exstyle = 0;
	wp->pClass = (PWNDCLASS)mwClassHead.head;
	wp->parent = NULL;
	wp->children = NULL;
	wp->siblings = NULL;
	wp->next = NULL;
	SetRect(&wp->winrect, 0, 0, psd->xvirtres, psd->yvirtres);
	MwCalcClientRect(wp);
	wp->cursor = NULL;
	wp->unmapcount = 0;
	wp->id = 0;
	strcpy(wp->szTitle, "Microwindows");
	wp->gotPaintMsg = PAINT_PAINTED;
#if UPDATEREGIONS
	wp->update = GdAllocRegion();
#endif

	listwp = wp;
	rootwp = wp;
	focuswp = wp;
	mousewp = wp;

	/* schedule desktop window paint*/
	InvalidateRect(rootwp, NULL, TRUE);

#if VTSWITCH
	MwInitVt();
	/* Check for VT change every 50 ms: */
	GdAddTimer(50, CheckVtChange, NULL);
#endif

	/*
	 * Initialize and position the default cursor.
	 */
	curcursor = NULL;
	cursorx = -1;
	cursory = -1;
	GdShowCursor(psd);
	MwMoveCursor(psd->xvirtres / 2, psd->yvirtres / 2);
	MwSetCursor(rootwp, &arrow);

	/*
	 * Finally tell the mouse driver some things.
	 */
	GdRestrictMouse(0, 0, psd->xvirtres - 1, psd->yvirtres - 1);
	GdMoveMouse(psd->xvirtres / 2, psd->yvirtres / 2);

	return 0;
}
Example #8
0
HWND WINAPI
CreateWindowEx(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName,
	DWORD dwStyle, int x, int y, int nWidth, int nHeight,
	HWND hwndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
{
	HWND		pwp;		/* parent window */
	HWND		wp;		/* new window */
	HWND		hwndOwner;
	PWNDCLASS	pClass;
	CREATESTRUCT	cs;
	int			titLen;
	static int	nextx = 20;
	static int	nexty = 20;
	
	/* WARNING: All modification made here should be reported 
	   on MwInitialize for the rootwp window */

	pClass = MwFindClassByName(lpClassName);
	if(!pClass)
		return NULL;

	if(x == CW_USEDEFAULT || y == CW_USEDEFAULT) {
		x = nextx;
		nextx += 10;
		y = nexty;
		nexty += 10;
		if(nextx > 200)
			nextx = nexty = 20;
	}
	if(nWidth == CW_USEDEFAULT || nHeight == CW_USEDEFAULT) {
		nWidth = 250;
		nHeight = 250;
	}

	if(hwndParent == NULL) {
		if(dwStyle & WS_CHILD)
			return NULL;
		pwp = rootwp;
	} else
		pwp = hwndParent;

	/* WS_POPUP z-order parent is the root window (passed parent is owner)*/
	if(dwStyle & WS_POPUP)
		pwp = rootwp;		/* force clip to root, not z-parent*/

	/* window owner is NULL for child windows, else it's the passed parent*/
	if(dwStyle & WS_CHILD)
		hwndOwner = NULL;
	else hwndOwner = hwndParent;

	wp = (HWND)GdItemAlloc(sizeof(struct hwnd) - 1 + pClass->cbWndExtra);
	if(!wp)
		return NULL;

	/* force all clipping on by default*/
	dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

	wp->pClass = pClass;
	wp->lpfnWndProc = pClass->lpfnWndProc;
	wp->style = dwStyle;
	wp->exstyle = dwExStyle;
	wp->parent = pwp;
	wp->owner = hwndOwner;
	wp->children = NULL;
	wp->siblings = pwp->children;
	pwp->children = wp;
	wp->next = listwp;
	listwp = wp;
	wp->winrect.left = pwp->clirect.left + x;
	wp->winrect.top = pwp->clirect.top + y;
	wp->winrect.right = wp->winrect.left + nWidth;
	wp->winrect.bottom = wp->winrect.top + nHeight;
	wp->cursor = pwp->cursor;
	wp->cursor->usecount++;
	wp->unmapcount = pwp->unmapcount + 1;
	wp->id = (int)hMenu;
	wp->gotPaintMsg = PAINT_PAINTED;

	titLen = 0;
	if (lpWindowName != NULL)
		titLen = strlen(lpWindowName);
	if (titLen < 64) titLen = 64; /* old mw compatibility */
	wp->szTitle = (LPTSTR)malloc(titLen + 1);
	if (wp->szTitle == NULL) {
		free(wp);
		return NULL;
	}
	if (lpWindowName != NULL)
		strcpy(wp->szTitle, lpWindowName);
	else
		wp->szTitle[0] = '\0';

#if UPDATEREGIONS
	wp->update = GdAllocRegion();
#endif
	wp->nextrabytes = pClass->cbWndExtra;
	wp->hInstance = hInstance;
	wp->nEraseBkGnd = 1;
	wp->paintBrush = NULL;
	wp->paintPen = NULL;

	/* calculate client area*/
	MwCalcClientRect(wp);

	cs.lpCreateParams = lpParam;
	cs.hInstance = hInstance;
	cs.hMenu = hMenu;
	cs.hwndParent = hwndParent;
	cs.cy = nHeight;
	cs.cx = nWidth;
	cs.y = y;
	cs.x = x;
	cs.style = dwStyle;
	cs.lpszName = lpWindowName;
	cs.lpszClass = lpClassName;
	cs.dwExStyle = dwExStyle;

	if(SendMessage(wp, WM_CREATE, 0, (LPARAM)(LPSTR)&cs) == -1) {
		MwDestroyWindow(wp, FALSE);
		return NULL;
	}

	/* send SIZE and MOVE msgs*/
	MwSendSizeMove(wp, TRUE, TRUE);

	if(wp->style & WS_VISIBLE) {
		MwShowWindow(wp, TRUE);
		SetFocus(wp);
	}

	return wp;
}
Example #9
0
/*
 *           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;
}
Example #10
0
/**
 * 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;
}