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

📄 srvfunc.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:
	
	regionp =  GsFindRegion(region);
	if (regionp)
		GdOffsetRegion(regionp->rgn, dx, dy);
}

/*
 * Return the bounding box for the specified region.
 */
int
GrGetRegionBox(GR_REGION_ID region, GR_RECT *rect)
{
	GR_REGION	*regionp;
	MWRECT		rc;
	int		ret_val;
	
	regionp =  GsFindRegion(region);
	if (regionp == NULL) {
		memset(rect, 0, sizeof(GR_RECT));
		return MWREGION_ERROR;
	}
	
	ret_val = GdGetRegionBox(regionp->rgn, &rc);
	/* convert MW rect to Nano-X rect*/
	rect->x = rc.left;
	rect->y = rc.top;
	rect->width = rc.right - rc.left;
	rect->height = rc.bottom - rc.top;
	return ret_val;
}

static int nextfontid = 1000;
/*
 * Allocate a new GC with default parameters.
 * The GC is owned by the current client.
 */
GR_FONT_ID
GrCreateFont(GR_CHAR *name, GR_COORD height, GR_LOGFONT *plogfont)
{
	GR_FONT	*fontp;

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

	if (plogfont)
		fontp->pfont = GdCreateFont(&scrdev, NULL, 0, plogfont);
	else
		fontp->pfont = GdCreateFont(&scrdev, name, height, NULL);
	fontp->id = nextfontid++;
	fontp->owner = curclient;
	fontp->next = listfontp;

	listfontp = fontp;

	return fontp->id;
}

/* Set the font size for the passed font*/
void
GrSetFontSize(GR_FONT_ID fontid, GR_COORD size)
{
	GR_FONT		*fontp;

	fontp = GsFindFont(fontid);
	if (fontp)
		GdSetFontSize(fontp->pfont, size);
}

/* Set the font rotation in tenths of degrees for the passed font*/
void
GrSetFontRotation(GR_FONT_ID fontid, int tenthdegrees)
{
	GR_FONT		*fontp;

	fontp = GsFindFont(fontid);
	if (fontp)
		GdSetFontRotation(fontp->pfont, tenthdegrees);
}

/* Set the font size for the passed font*/
void
GrSetFontAttr(GR_FONT_ID fontid, int setflags, int clrflags)
{
	GR_FONT		*fontp;

	fontp = GsFindFont(fontid);
	if (fontp)
		GdSetFontAttr(fontp->pfont, setflags, clrflags);
}

/*
 * Unload and deallocate an existing font.
 */
void
GrDestroyFont(GR_FONT_ID fontid)
{
	GR_FONT		*fontp;
	GR_FONT		*prevfontp;

	fontp = GsFindFont(fontid);
	if (fontp == NULL)
		return;

	if (listfontp == fontp)
		listfontp = fontp->next;
	else {
		prevfontp = listfontp;
		while (prevfontp->next != fontp)
			prevfontp = prevfontp->next;

		prevfontp->next = fontp->next;
	}
	GdDestroyFont(fontp->pfont);
	free(fontp);
}

/*
 * Return useful information about the specified font.
 * Font #0 returns info about the standard font.
 */
void
GrGetFontInfo(GR_FONT_ID font, GR_FONT_INFO *fip)
{
	GR_FONT	*fontp;
	PMWFONT	pf;

	if (font == 0)
		pf = stdfont;
	else {
		fontp = GsFindFont(font);
		if (!fontp) {
			memset(fip, 0, sizeof(GR_FONT_INFO));
			return;
		}
		pf = fontp->pfont;
	}
	GdGetFontInfo(pf, fip);
}

/*
 * Select events for a window for this client.
 * The events are a bitmask for the events desired.
 */
void 
GrSelectEvents(GR_WINDOW_ID wid, GR_EVENT_MASK eventmask)
{
	GR_WINDOW	*wp;		/* window structure */
	GR_EVENT_CLIENT	*evp;		/* event-client structure */

	wp = GsFindWindow(wid);
	if (wp == NULL)
		return;

	/*
	 * See if this client is already in the event client list.
	 * If so, then just replace the events he is selecting for.
	 */
	for (evp = wp->eventclients; evp; evp = evp->next) {
		if (evp->client == curclient) {
			evp->eventmask = eventmask;
			return;
		}
	}

	/*
	 * A new client for this window, so allocate a new event client
	 * structure and insert it into the front of the list in the window.
	 */
	evp = (GR_EVENT_CLIENT *) malloc(sizeof(GR_EVENT_CLIENT));
	if (evp == NULL) {
		GsError(GR_ERROR_MALLOC_FAILED, wid);
		return;
	}

	evp->client = curclient;
	evp->eventmask = eventmask;
	evp->next = wp->eventclients;
	wp->eventclients = evp;

	/*
	 * If it's a request for child updates to the root window,
	 * then search entire list and send map events for
	 * mapped windows now.  This allows a window manager
	 * to get the mapped window list without another API call.
	 */
	if (wid==GR_ROOT_WINDOW_ID && (eventmask & GR_EVENT_MASK_CHLD_UPDATE)) {
		for (wp = listwp; wp; wp = wp->next) {
			if (wp->unmapcount == 0)
				GsDeliverUpdateEvent(wp, GR_UPDATE_MAP,
					wp->x, wp->y, wp->width, wp->height);
		}
	}
}

static GR_WINDOW *
NewWindow(GR_WINDOW *pwp, GR_COORD x, GR_COORD y, GR_SIZE width,
	GR_SIZE height, GR_SIZE bordersize, GR_COLOR background,
	GR_COLOR bordercolor)
{
	GR_WINDOW	*wp;	/* new window*/

	if (width <= 0 || height <= 0 || bordersize < 0) {
		GsError(GR_ERROR_BAD_WINDOW_SIZE, 0);
		return NULL;
	}

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

	wp->id = nextid++;
	wp->psd = rootwp->psd;
	wp->parent = pwp;
	wp->children = NULL;
	wp->siblings = pwp->children;
	wp->next = listwp;
	wp->x = pwp->x + x;
	wp->y = pwp->y + y;
	wp->width = width;
	wp->height = height;
	wp->bordersize = bordersize;
	wp->background = background;
	wp->bgpixmap = NULL;
	wp->bgpixmapflags = GR_BACKGROUND_TILE;
	wp->bordercolor = bordercolor;
	wp->nopropmask = 0;
	wp->eventclients = NULL;
	wp->owner = curclient;
	wp->cursorid = pwp->cursorid;
	wp->mapped = GR_FALSE;
	wp->unmapcount = pwp->unmapcount + 1;
	wp->output = GR_TRUE;
	wp->props = 0;
	wp->title = NULL;

	pwp->children = wp;
	listwp = wp;

	return wp;
}

/*
 * Allocate a new window which is a child of the specified window.
 * The window inherits the cursor of the parent window.
 * The window is owned by the current client.
 */
GR_WINDOW_ID
GrNewWindow(GR_WINDOW_ID parent, GR_COORD x, GR_COORD y, GR_SIZE width,
	GR_SIZE height, GR_SIZE bordersize, GR_COLOR background,
	GR_COLOR bordercolor)
{
	GR_WINDOW	*pwp;		/* parent window */
	GR_WINDOW	*wp;		/* new window */

	pwp = GsFindWindow(parent);
	if (pwp == NULL)
		return 0;

	if (!pwp->output) {
		GsError(GR_ERROR_INPUT_ONLY_WINDOW, pwp->id);
		return 0;
	}

	wp = NewWindow(pwp, x, y, width, height, bordersize, background,
		bordercolor);
	return wp? wp->id: 0;
}

/*
 * Allocate a new input-only window which is a child of the specified window.
 * Such a window is invisible, cannot be drawn into, and is only used to
 * return events.  The window inherits the cursor of the parent window.
 * The window is owned by the current client.
 */
GR_WINDOW_ID
GrNewInputWindow(GR_WINDOW_ID parent, GR_COORD x, GR_COORD y,
	GR_SIZE width, GR_SIZE height)
{
	GR_WINDOW	*pwp;		/* parent window */
	GR_WINDOW	*wp;		/* new window */

	pwp = GsFindWindow(parent);
	if (pwp == NULL)
		return 0;

	wp = NewWindow(pwp, x, y, width, height, 0, BLACK, BLACK);
	if (wp) {
		/* convert to input-only window*/
		wp->output = GR_FALSE;
		return wp->id;
	}
	return 0;
}

/*
 * Allocate a pixmap, can be used with any drawing functions
 * for offscreen drawing
 */
GR_WINDOW_ID
GrNewPixmap(GR_SIZE width, GR_SIZE height, void * pixels)
{
	GR_PIXMAP	*pp;
	PSD		psd;
        int 		size, linelen, bpp, planes;
   
	if (width <= 0 || height <= 0) {
		/* no error for now, server will desynchronize w/app*/
		/*GsError(GR_ERROR_BAD_WINDOW_SIZE, 0);*/
		return 0;
	}

	/*
	 * allocate offscreen psd.  If screen driver doesn't
	 * support blitting, this will fail.  Use root window screen
	 * device for compatibility for now.
	 */
	planes = rootwp->psd->planes;
	bpp = rootwp->psd->bpp;
        psd = rootwp->psd->AllocateMemGC(rootwp->psd);
	if (!psd)
		return 0;

	pp = (GR_PIXMAP *) malloc(sizeof(GR_PIXMAP));
	if (pp == NULL) {
		GsError(GR_ERROR_MALLOC_FAILED, 0);
		psd->FreeMemGC(psd);
		return 0;
	}

        GdCalcMemGCAlloc(psd, width, height, 0, 0, &size, &linelen);

	/* Allocate space for pixel values */
        if (!pixels) {
	        pixels = calloc(size, 1);
		psd->flags |= PSF_ADDRMALLOC;
	}
	if (!pixels) {
		free(pp);
		psd->FreeMemGC(psd);
		GsError(GR_ERROR_MALLOC_FAILED, 0);
		return 0;
	}
  
	pp->id = nextid++;
	pp->next = listpp;
	pp->psd = psd;
	pp->x = 0;
	pp->y = 0;
	pp->width = width;
	pp->height = height;
	pp->owner = curclient;

        psd->MapMemGC(psd, width, height, planes, bpp, linelen, size,
		pixels);
	
        listpp = pp;
	return pp->id;
}

/*
 * Map the window to make it (and possibly its children) visible on the screen.
 */
void
GrMapWindow(GR_WINDOW_ID wid)
{
	GR_WINDOW	*wp;		/* window structure */

	wp = GsFindWindow(wid);
	if (!wp || wp->mapped)
		return;

	wp->mapped = GR_TRUE;

	GsWpMapWindow(wp, GR_FALSE);
}

/*
 * Unmap the window to make it and its children invisible on the screen.
 */
void
GrUnmapWindow(GR_WINDOW_ID wid)
{
	GR_WINDOW	*wp;		/* window structure */

	wp = GsFindWindow(wid);
	if (!wp || !wp->mapped)
		return;

	GsWpUnmapWindow(wp, GR_FALSE);

	wp->mapped = GR_FALSE;
}

/*
 * Clear the associated area of a window to its background color
 * or pixmap.  Generate expose event for window if exposeflag set.
 */
void
GrClearArea(GR_WINDOW_ID wid, GR_COORD x, GR_COORD y, GR_SIZE width,
	GR_SIZE height, GR_BOOL exposeflag)
{
	GR_WINDOW		*wp;	/* window structure */

	wp = GsPrepareWindow(wid);
	if (wp) {
		if (width == 0)
			width = wp->width;
		if (height == 0)
			height = wp->height;
		GsWpClearWindow(wp, x, y, width, height, exposeflag);
	}
}

/* Return window with keyboard focus.*/
GR_WINDOW_ID
GrGetFocus(void)
{
	return focuswp->id;
}

/*
 * Set the focus to a particular window.
 * This makes keyboard events only visible to that window or children of it,
 * depending on the pointer location.
 */
void
GrSetFocus(GR_WINDOW_ID wid)
{
	GR_WINDOW	*wp;		/* window structure */

	wp = GsFindWindow(wid);
	if (wp == NULL)
		return;

	if (wp->unmapcount) {
		GsError(GR_ERROR_UNMAPPED_FOCUS_WINDOW, wid);
		return;
	}

	/* Check if window wants focus, if not, ignore call*/
	if (wp->props & GR_WM_PROPS_NOFOCUS)
		return;

	focusfixed = (wp != rootwp);
	GsWpSetFocus(wp);
}

/*
 * Create a new server-based cursor resource.
 */
static int nextcursorid = 1000;
GR_CURSOR_ID
GrNewCursor(GR_SIZE width, GR_SIZE height, GR_COORD hotx, GR_COORD hoty,
	GR_COLOR foreground, GR_COLOR background, GR_BITMAP *fgbitmap,
	GR_BITMAP *bgbitmap)
{
	GR_CURSOR	*cp;
	int		bytes;

	/*
	 * Make sure the size of the bitmap is reasonable.
	 */
	if (width <= 0 || width > MWMAX_CURSOR_SIZE ||
	    height <= 0 || height > MWMAX_CURSOR_SIZE) {
		GsError(GR_ERROR_BAD_CURSOR_SIZE, 0);
		return 0;
	}

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

	/* fill in cursor structure*/
	cp->cursor.width = width;
	cp->cursor.height = height;
	cp->cursor.hotx = hotx;
	cp->cursor.hoty = hoty;
	cp->cursor.fgcolor = foreground;
	cp->cursor.bgcolor = background;
	bytes = GR_BITMAP_SIZE(width, height) * sizeof(GR_BITMAP);
	memcpy(&cp->cursor.image, fgbitmap, bytes);
	memcpy(&cp->cursor.mask, bgbitmap, bytes);

	cp->id = nextcursorid++;
	cp->owner = curclient;
	cp->next = listcursorp;
	listcursorp = cp;

	return cp->id;
}

/*
 * Destroy a server-based cursor.
 */
void
GrDestroyCursor(GR_CURSOR_ID cid)
{
	GR_CURSOR	*cursorp;
	GR_CURSOR	*prevcursorp;

	cursorp = GsFindCursor(cid);
	if (cursorp == NULL)
		return;

	if (listcursorp == cursorp)
		listcursorp = cursorp->next;
	else {
		prevcursorp = listcursorp;
		while (prevcursorp->next != cursorp)
			prevcursorp = prevcursorp->next;

		prevcursorp->next = cursorp->next;
	}

	if (curcursor == cursorp)
		curcursor = NULL;

	free(cursorp);
	GsCheckCursor();
}

/*
 * Specify a cursor for a window.
 * This cursor will only be used within that window, and by default
 * for its new children.  If the cursor is currently within this
 * window, it will be changed to the new one immediately.
 * If the new cursor id is 0, revert to the root window cursor.
 */
void
GrSetWindowCursor(GR_WINDOW_ID wid, GR_CURSOR_ID cid)
{
	GR_WINDOW	*wp;
	GR_CURSOR	*cp;		/* cursor structure */

	wp = GsFindWindow(wid);
	if (wp == NULL)
		return;

	if (cid == 0)
		cp = stdcursor;
	else {
		cp = GsFindCursor(cid);
		if (!cp)
			return;		/* FIXME add server errmsg*/
	}
	wp->cursorid = cid;

⌨️ 快捷键说明

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