📄 srvutil.c
字号:
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;}#endif /* MW_FEATURE_TIMERS *//* * 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_TYPEGsPrepareDrawing(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->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) { /* 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) { PSD psd = (wp ? wp->psd : pp->psd); unsigned long 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); 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; } 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->realized) 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->realized && ((!wp->clipregion && (wp->x <= x) && (wp->y <= y) && (wp->x + wp->width > x) && (wp->y + wp->height > y)) || (wp->clipregion && GdPtInRegion(wp->clipregion, x - wp->x, y - wp->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. */voidGsCheckCursor(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. */voidGsCheckMouseWindow(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. */voidGsCheckFocusWindow(void){ GR_WINDOW *wp; /* current window */ GR_EVENT_CLIENT *ecp; /* current event client */ if (focusfixed) return; /* * 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 & GR_EVENT_MASK_KEY_DOWN) { GsWpSetFocus(wp); return; } } if ((wp == rootwp) || (wp->nopropmask & GR_EVENT_MASK_KEY_DOWN)) { GsWpSetFocus(rootwp); return; } }}/* Send an update activate event to top level window of passed window*/voidGsWpNotifyActivate(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. */voidGsWpSetFocus(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. */voidGsSetPortraitMode(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. */voidGsSetPortraitModeFromXY(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 + -