📄 srvutil.c
字号:
topy = wp->y; boty = bminy - 1; wp->x -= bs; wp->y -= bs; wp->width += (bs * 2); wp->height += (bs * 2); wp->bordersize = 0; clipwp = NULL; GsSetClipWindow(wp, NULL, 0); curgcp = NULL; GdSetMode(GR_MODE_COPY); GdSetForeground(GdFindColor(wp->bordercolor)); if (bs == 1) { GdLine(wp->psd, lminx, tminy, rminx, tminy, TRUE); GdLine(wp->psd, lminx, bminy, rminx, bminy, TRUE); GdLine(wp->psd, lminx, topy, lminx, boty, TRUE); GdLine(wp->psd, rminx, topy, rminx, boty, TRUE); } else { GdFillRect(wp->psd, lminx, tminy, width + bs * 2, bs); GdFillRect(wp->psd, lminx, bminy, width + bs * 2, bs); GdFillRect(wp->psd, lminx, topy, bs, height); GdFillRect(wp->psd, rminx, topy, bs, height); } /* * Restore the true window size. * Forget the currently clipped window since we messed it up. */ wp->x += bs; wp->y += bs; wp->width -= (bs * 2); wp->height -= (bs * 2); wp->bordersize = bs; clipwp = NULL;}/* * Check to see if the first window overlaps the second window. */GR_BOOL GsCheckOverlap(GR_WINDOW *topwp, GR_WINDOW *botwp){ GR_COORD minx1; GR_COORD miny1; GR_COORD maxx1; GR_COORD maxy1; GR_COORD minx2; GR_COORD miny2; GR_COORD maxx2; GR_COORD maxy2; GR_SIZE bs; if (!topwp->output || topwp->unmapcount || botwp->unmapcount) return GR_FALSE; bs = topwp->bordersize; minx1 = topwp->x - bs; miny1 = topwp->y - bs; maxx1 = topwp->x + topwp->width + bs - 1; maxy1 = topwp->y + topwp->height + bs - 1; bs = botwp->bordersize; minx2 = botwp->x - bs; miny2 = botwp->y - bs; maxx2 = botwp->x + botwp->width + bs - 1; maxy2 = botwp->y + botwp->height + bs - 1; if ((minx1 > maxx2) || (minx2 > maxx1) || (miny1 > maxy2) || (miny2 > maxy1)) return GR_FALSE; return GR_TRUE;}/* * Return a pointer to the window structure with the specified window id. * Returns NULL if the window does not exist. */GR_WINDOW *GsFindWindow(GR_WINDOW_ID id){ GR_WINDOW *wp; /* current window pointer */ /* * See if this is the root window or the same window as last time. */ if (id == GR_ROOT_WINDOW_ID) return rootwp; if ((id == cachewindowid) && id) return cachewp; /* * No, search for it and cache it for future calls. */ for (wp = listwp; wp; wp = wp->next) { if (wp->id == id) { cachewindowid = id; cachewp = wp; return wp; } } return NULL;}/* * Return a pointer to the pixmap structure with the specified window id. * Returns NULL if the pixmap does not exist. */GR_PIXMAP *GsFindPixmap(GR_WINDOW_ID id){ GR_PIXMAP *pp; /* current pixmap pointer */ if ((id == cachepixmapid) && id) return cachepp; /* * No, search for it and cache it for future calls. */ for (pp = listpp; pp; pp = pp->next) { if (pp->id == id) { cachepixmapid = id; cachepp = pp; return pp; } } return NULL;}/* * Return a pointer to the graphics context with the specified id. * Returns NULL if the graphics context does not exist, with an * error saved. */GR_GC *GsFindGC(GR_GC_ID gcid){ GR_GC *gcp; /* current graphics context pointer */ /* * See if this is the same graphics context as last time. */ if ((gcid == cachegcid) && gcid) return cachegcp; /* * No, search for it and cache it for future calls. */ for (gcp = listgcp; gcp; gcp = gcp->next) { if (gcp->id == gcid) { cachegcid = gcid; cachegcp = gcp; return gcp; } } GsError(GR_ERROR_BAD_GC_ID, gcid); return NULL;}/* Return a pointer to the region with the specified id.*/GR_REGION *GsFindRegion(GR_REGION_ID regionid){ GR_REGION *regionp; /* current region pointer */ for (regionp = listregionp; regionp; regionp = regionp->next) { if (regionp->id == regionid) { return regionp; } } return NULL;}/* find a font with specified id*/GR_FONT *GsFindFont(GR_FONT_ID fontid){ GR_FONT *fontp; for (fontp = listfontp; fontp; fontp = fontp->next) { if (fontp->id == fontid) return fontp; } return NULL;}/* find a cursor with specified id*/GR_CURSOR *GsFindCursor(GR_CURSOR_ID cursorid){ GR_CURSOR *cursorp; for (cursorp = listcursorp; cursorp; cursorp = cursorp->next) { if (cursorp->id == cursorid) return cursorp; } 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 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. */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. */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 + -