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

📄 srvutil.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 3 页
字号:
	}
	return NULL;
}

GR_TIMER *
GsFindTimer (GR_TIMER_ID timer_id)
{
    GR_TIMER   *timer;
    
    /*
     * See if this is the same graphics context as last time.
     */
    if ((timer_id == cache_timer_id) && timer_id)
        return cache_timer;
    
    /*
     * No, search for it and cache it for future calls.
     */
    for (timer = list_timer; timer != NULL; timer = timer->next) 
    {
        if (timer->id == timer_id) 
        {
            cache_timer_id = timer_id;
            cache_timer = timer;
            return timer;
        }
    }
    return NULL;
}


/*
 * 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;
}

/*
 * Prepare the specified window for drawing into it.
 * This sets up the clipping regions to just allow drawing into it.
 * Returns NULL if the drawing is illegal (with an error generated),
 * or if the window is not mapped.
 */
GR_WINDOW *GsPrepareWindow(GR_WINDOW_ID wid)
{
	GR_WINDOW	*wp;		/* found window */

	wp = GsFindWindow(wid);
	if (wp == NULL)
		return NULL;
	
	if (!wp->output) {
		GsError(GR_ERROR_INPUT_ONLY_WINDOW, wid);
		return NULL;
	}

	if (wp->unmapcount)
		return NULL;

	if (wp != clipwp) {
		/* FIXME: no user region clipping here*/
		GsSetClipWindow(wp, NULL, 0);
	}

	return wp;
}

/*
 * Find the window which is currently visible for the specified coordinates.
 * This just walks down the window tree looking for the deepest mapped
 * window which contains the specified point.  If the coordinates are
 * off the screen, the root window is returned.
 */
GR_WINDOW *GsFindVisibleWindow(GR_COORD x, GR_COORD y)
{
	GR_WINDOW	*wp;		/* current window */
	GR_WINDOW	*retwp;		/* returned window */

	wp = rootwp;
	retwp = wp;
	while (wp) {
		if ((wp->unmapcount == 0) && (wp->x <= x) && (wp->y <= y) &&
			(wp->x + wp->width > x) && (wp->y + wp->height > y))
		{
			retwp = wp;
			wp = wp->children;
			continue;
		}
		wp = wp->siblings;
	}
	return retwp;
}

/*
 * Check to see if the cursor shape is the correct shape for its current
 * location.  If not, its shape is changed.
 */
void GsCheckCursor(void)
{
	GR_WINDOW	*wp;		/* window cursor is in */
	GR_CURSOR	*cp;		/* cursor definition */

	/*
	 * Get the cursor at its current position, and if it is not the
	 * currently defined one, then set the new cursor.  However,
	 * if the pointer is currently grabbed, then leave it alone.
	 */
	wp = grabbuttonwp;
	if (wp == NULL)
		wp = mousewp;

	cp = GsFindCursor(wp->cursorid);
	if (!cp)
		cp = stdcursor;
	if (cp == curcursor)
		return;

	/*
	 * It needs redefining, so do it.
	 */
	curcursor = cp;
	GdMoveCursor(cursorx - cp->cursor.hotx, cursory - cp->cursor.hoty);
	GdSetCursor(&cp->cursor);
}

/*
 * Check to see if the window the mouse is currently in has changed.
 * If so, generate enter and leave events as required.  The newest
 * mouse window is remembered in mousewp.  However, do not change the
 * window while it is grabbed.
 */
void GsCheckMouseWindow(void)
{
	GR_WINDOW	*wp;		/* newest window for mouse */

	wp = grabbuttonwp;
	if (wp == NULL)
		wp = GsFindVisibleWindow(cursorx, cursory);
	if (wp == mousewp)
		return;

	GsDeliverGeneralEvent(mousewp, GR_EVENT_TYPE_MOUSE_EXIT, NULL);

	mousewp = wp;

	GsDeliverGeneralEvent(wp, GR_EVENT_TYPE_MOUSE_ENTER, NULL);
}

/*
 * Determine the current focus window for the current mouse coordinates.
 * The mouse coordinates only matter if the focus is not fixed.  Otherwise,
 * the selected window is dependant on the window which wants keyboard
 * events.  This also sets the current focus for that found window.
 * The window with focus is remembered in focuswp.
 */
void GsCheckFocusWindow(void)
{
	GR_WINDOW		*wp;		/* current window */
	GR_EVENT_CLIENT		*ecp;		/* current event client */
	GR_EVENT_MASK		eventmask;	/* event mask */

	if (focusfixed)
		return;

	eventmask = GR_EVENT_MASK_KEY_DOWN;

	/*
	 * Walk upwards from the current window containing the mouse
	 * looking for the first window which would accept a keyboard event.
	 */
	for (wp = mousewp; ;wp = wp->parent) {
		if (wp->props & GR_WM_PROPS_NOFOCUS)
			continue;
		for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
			if (ecp->eventmask & eventmask) {
				GsWpSetFocus(wp);
				return;
			}
		}
		if ((wp == rootwp) || (wp->nopropmask & eventmask)) {
			GsWpSetFocus(rootwp);
			return;
		}
	}
}

/* Send an update activate event to top level window of passed window*/
static void
GsWpNotifyActivate(GR_WINDOW *wp)
{
	GR_WINDOW	*pwp;

	for (pwp=wp; pwp->parent; pwp=pwp->parent)
		if (pwp->parent->id == GR_ROOT_WINDOW_ID)
			break;
	if (pwp->id != GR_ROOT_WINDOW_ID)
		GsDeliverUpdateEvent(pwp, GR_UPDATE_ACTIVATE, 0, 0, 0, 0);
}

/*
 * Set the input focus to the specified window.
 * This generates focus out and focus in events as necessary.
 */
void GsWpSetFocus(GR_WINDOW *wp)
{
	GR_WINDOW	*oldfocus;

	if (wp == focuswp)
		return;

	GsDeliverGeneralEvent(focuswp, GR_EVENT_TYPE_FOCUS_OUT, wp);
	GsWpNotifyActivate(focuswp);

	oldfocus = focuswp;
	focuswp = wp;

	GsDeliverGeneralEvent(wp, GR_EVENT_TYPE_FOCUS_IN, oldfocus);
	GsWpNotifyActivate(focuswp);
}

/*
 * Set dynamic portrait mode and redraw screen.
 */
void
GsSetPortraitMode(int mode)
{
	GdSetPortraitMode(&scrdev, mode);
	GdRestrictMouse(0, 0, scrdev.xvirtres - 1, scrdev.yvirtres - 1);

	/* reset clip and root window size*/
	clipwp = NULL;
	rootwp->width = scrdev.xvirtres;
	rootwp->height = scrdev.yvirtres;

	/* deliver portrait changed event to all windows selecting it*/
	GsDeliverPortraitChangedEvent();
	
	/* redraw screen - apps may redraw/resize again causing flicker*/
	GsRedrawScreen();
}

/*
 * Check mouse coordinates and possibly set indicated portrait
 * mode from mouse position.
 */
void
GsSetPortraitModeFromXY(GR_COORD rootx, GR_COORD rooty)
{
	int newmode;

	if (rootx == 0) {
		/* rotate left*/
		switch (scrdev.portrait) {
		case MWPORTRAIT_NONE:
		default:
			newmode = MWPORTRAIT_LEFT;
			break;
		case MWPORTRAIT_LEFT:
			newmode = MWPORTRAIT_DOWN;
			break;
		case MWPORTRAIT_DOWN:
			newmode = MWPORTRAIT_RIGHT;
			break;
		case MWPORTRAIT_RIGHT:
			newmode = MWPORTRAIT_NONE;
			break;
		}
		GsSetPortraitMode(newmode);
		GrMoveCursor(5, rooty);
		GdMoveMouse(5, rooty);
	} else if (rootx == scrdev.xvirtres-1) {
		/* rotate right*/
		switch (scrdev.portrait) {
		case MWPORTRAIT_NONE:
		default:
			newmode = MWPORTRAIT_RIGHT;
			break;
		case MWPORTRAIT_LEFT:
			newmode = MWPORTRAIT_NONE;
			break;
		case MWPORTRAIT_DOWN:
			newmode = MWPORTRAIT_LEFT;
			break;
		case MWPORTRAIT_RIGHT:
			newmode = MWPORTRAIT_DOWN;
			break;
		}
		GsSetPortraitMode(newmode);
		GrMoveCursor(scrdev.xvirtres-5, rooty);
		GdMoveMouse(scrdev.xvirtres-5, rooty);
	}
}

⌨️ 快捷键说明

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