📄 srvutil.c
字号:
/* * Copyright (c) 2000, 2002 Greg Haerr <greg@censoft.com> * Portions Copyright (c) 2002 by Koninklijke Philips Electronics N.V. * Copyright (c) 1991 David I. Bell * Permission is granted to use, distribute, or modify this source, * provided that this copyright notice remains intact. * * Graphics server utility routines for windows. */#include <stdio.h>#include <stdlib.h>#ifndef __PACIFIC__#include <fcntl.h>#endif#include "serv.h"/* * Redraw the screen completely. */voidGsRedrawScreen(void){ /* Redraw all windows*/ GsExposeArea(rootwp, 0, 0, rootwp->width, rootwp->height, NULL);}/* * Activate Screen Saver. */voidGsActivateScreenSaver(void *arg){ screensaver_active = GR_TRUE; GsDeliverScreenSaverEvent(GR_TRUE);}/* * Deactivate screen saver and reset timer if active. */voidGsResetScreenSaver(void){#if MW_FEATURE_TIMERS MWTIMER *timer;#endif /* MW_FEATURE_TIMERS */ if(screensaver_active == GR_TRUE) { screensaver_active = GR_FALSE; GsDeliverScreenSaverEvent(GR_FALSE); }#if MW_FEATURE_TIMERS if(screensaver_delay) { if((timer = GdFindTimer(GsActivateScreenSaver))) GdDestroyTimer(timer); GdAddTimer(screensaver_delay, GsActivateScreenSaver, GsActivateScreenSaver); }#endif /* MW_FEATURE_TIMERS */}#if MW_FEATURE_TIMERSvoidGsTimerCB (void *arg) { GR_TIMER *timer = (GR_TIMER*) arg; GsDeliverTimerEvent (timer->owner, timer->wid, timer->id);}#endif /* MW_FEATURE_TIMERS *//* * Unmap the window to make it and its children invisible on the screen. * This is a recursive routine which unrealizes this window and all of its * children, and causes exposure events for windows which are newly uncovered. * If temp_unmap set, don't reset focus or generate mouse/focus events, * as window will be mapped again momentarily (window move, resize, etc) */voidGsWpUnrealizeWindow(GR_WINDOW *wp, GR_BOOL temp_unmap){ GR_WINDOW *pwp; /* parent window */ GR_WINDOW *sibwp; /* sibling window */ GR_WINDOW *childwp; /* child window */ GR_SIZE bs; /* border size of this window */ if (wp == rootwp) { GsError(GR_ERROR_ILLEGAL_ON_ROOT_WINDOW, wp->id); return; } if (wp == clipwp) clipwp = NULL; /* if window isn't realized, nothing to do*/ if (!wp->realized) return; /* set window invisible flag*/ wp->realized = GR_FALSE; for (childwp = wp->children; childwp; childwp = childwp->siblings) GsWpUnrealizeWindow(childwp, temp_unmap); if (!temp_unmap && wp == mousewp) { GsCheckMouseWindow(); GsCheckCursor(); } if (!temp_unmap && wp == focuswp) { if (focusfixed) /* don't revert to mouse enter/leave focus if fixed*/ focuswp = rootwp; else { focusfixed = GR_FALSE; GsCheckFocusWindow(); } } /* Send unmap update event*/ GsDeliverUpdateEvent(wp, (temp_unmap? GR_UPDATE_UNMAPTEMP: GR_UPDATE_UNMAP), 0, 0, 0, 0); /* * If this is an input-only window or the parent window is * still unrealized, then we are all done. */ if (!wp->parent->realized || !wp->output) return; /* * Clear the area in the parent for this window, causing an * exposure event for it. Take into account the border size. */ bs = wp->bordersize; pwp = wp->parent; GsWpClearWindow(pwp, wp->x - pwp->x - bs, wp->y - pwp->y - bs, wp->width + bs * 2, wp->height + bs * 2, GR_TRUE); /* * Finally clear and redraw all parts of our lower sibling * windows that were covered by this window. */ sibwp = wp; while (sibwp->siblings) { sibwp = sibwp->siblings; GsExposeArea(sibwp, wp->x - bs, wp->y - bs, wp->width + bs * 2, wp->height + bs * 2, NULL); }}/* * Map the window to possibly make it and its children visible on the screen. * This is a recursive routine which realizes this window and all of its * children, and causes exposure events for those windows which become visible. * If temp is set, then window is being mapped again after a temporary * unmap, so don't reset focus or generate mouse/focus events. */voidGsWpRealizeWindow(GR_WINDOW *wp, GR_BOOL temp){ if (wp == rootwp) { GsError(GR_ERROR_ILLEGAL_ON_ROOT_WINDOW, wp->id); return; }/*printf("RealizeWindow %d, map %d realized %d, parent_realized %d\n",wp->id, wp->mapped, wp->realized, wp->parent->realized);*/#define OLDWAY 0#if OLDWAY /* old way, doesn't quite work with unmap/map yourself*/ /* * If window is already realized, or if window * isn't set to be mapped, or parent isn't * realized, then we're done */ if (wp->realized || !wp->mapped || !wp->parent->realized) return;#else /* new way, still small bug with xfreecell and popup windows*/ /* if window is already realized, we're done*/ if (wp->realized) return; /* * Send map update event for window manager or others */ /* send map update event if not temp unmap/map*/ if (!temp) { GsDeliverUpdateEvent(wp, GR_UPDATE_MAP, wp->x, wp->y, wp->width, wp->height); } /* * If window isn't set to be mapped, or parent isn't * realized, then we're done */ if (!wp->mapped || !wp->parent->realized) return;#endif /* set window visible flag*/ wp->realized = GR_TRUE; if (!temp) { GsCheckMouseWindow(); GsCheckFocusWindow(); GsCheckCursor(); }#if OLDWAY /* send map update event if not temp unmap/map*/ if (!temp) { GsDeliverUpdateEvent(wp, GR_UPDATE_MAP, wp->x, wp->y, wp->width, wp->height); }#endif /* * If the window is an output window, then draw its border, * clear it to the background color, and generate an exposure event. */ if (wp->output) { GsDrawBorder(wp); GsWpClearWindow(wp, 0, 0, wp->width, wp->height, GR_TRUE); } /* * Do the same thing for the children. */ for (wp = wp->children; wp; wp = wp->siblings) GsWpRealizeWindow(wp, temp);}/* * Destroy the specified window, and all of its children. * This is a recursive routine. */voidGsWpDestroyWindow(GR_WINDOW *wp){ GR_WINDOW *prevwp; /* previous window pointer */ GR_EVENT_CLIENT *ecp; /* selections for window */ GR_WINDOW_ID oldwid; /* old selection owner */ GR_GRABBED_KEY *keygrab; GR_GRABBED_KEY **keygrab_prev_next; if (wp == rootwp) { GsError(GR_ERROR_ILLEGAL_ON_ROOT_WINDOW, wp->id); return; } /* Disable selection if this window is the owner */ if(selection_owner.wid == wp->id) { oldwid = selection_owner.wid; selection_owner.wid = 0; if(selection_owner.typelist) free(selection_owner.typelist); GsDeliverSelectionChangedEvent(oldwid, 0); } /* * Unmap the window first. */ if (wp->realized) GsWpUnrealizeWindow(wp, GR_FALSE); /* send destroy update event*/ GsDeliverUpdateEvent(wp, GR_UPDATE_DESTROY, wp->x, wp->y, wp->width, wp->height); /* * Destroy all children. */ while (wp->children) GsWpDestroyWindow(wp->children); /* * Free all client selection structures. */ while (wp->eventclients) { ecp = wp->eventclients; wp->eventclients = ecp->next; free(ecp); } /* * Remove this window from the child list of its parent. */ prevwp = wp->parent->children; if (prevwp == wp) wp->parent->children = wp->siblings; else { while (prevwp->siblings != wp) prevwp = prevwp->siblings; prevwp->siblings = wp->siblings; } wp->siblings = NULL; /* * Remove this window from the complete list of windows. */ prevwp = listwp; if (prevwp == wp) listwp = wp->next; else { while (prevwp->next != wp) prevwp = prevwp->next; prevwp->next = wp->next; } wp->next = NULL; /* * Forget various information if they related to this window. * Then finally free the structure. */ if (wp == clipwp) clipwp = NULL; if (wp == grabbuttonwp) grabbuttonwp = NULL; if (wp == cachewp) { cachewindowid = 0; cachewp = NULL; } if (wp == focuswp) { /* don't revert to mouse enter/leave focus if fixed*/ /*focusfixed = GR_FALSE;*/ focuswp = rootwp; } GsCheckMouseWindow(); if(wp->title) free(wp->title); if (wp->clipregion) GdDestroyRegion(wp->clipregion); /* Remove any grabbed keys for this window. */ keygrab_prev_next = &list_grabbed_keys; keygrab = list_grabbed_keys; while (keygrab != NULL) { if (keygrab->wid == wp->id){ /* Delete keygrab. */ *keygrab_prev_next = keygrab->next; free(keygrab); keygrab = *keygrab_prev_next; } else { keygrab_prev_next = &keygrab->next; keygrab = keygrab->next; } } free(wp);}/* * Draw a window's background pixmap. * * The flags mean: * GR_BACKGROUND_TILE- tile the pixmap across the window (default). * GR_BACKGROUND_TOPLEFT- draw the pixmap at (0,0) relative to the window. * GR_BACKGROUND_CENTER- draw the pixmap in the middle of the window. * GR_BACKGROUND_STRETCH- stretch the pixmap within the window. * GR_BACKGROUND_TRANS- if the pixmap is smaller than the window and not * using tile mode, there will be gaps around the pixmap. This flag causes * to not fill in the spaces with the background colour. */voidGsWpDrawBackgroundPixmap(GR_WINDOW *wp, GR_PIXMAP *pm, GR_COORD x, GR_COORD y, GR_SIZE width, GR_SIZE height){ GR_SIZE destwidth, destheight, fillwidth, fillheight, pmwidth, pmheight; GR_COORD fromx, fromy, destx, desty, pixmapx = 0, pixmapy = 0; if(wp->bgpixmapflags & (GR_BACKGROUND_TOPLEFT|GR_BACKGROUND_STRETCH)) { pixmapx = 0; pixmapy = 0; } else if(wp->bgpixmapflags & GR_BACKGROUND_CENTER) { if(pm->width >= wp->width) pixmapx = 0; else pixmapx = (wp->width - pm->width) / 2; if(pm->height >= wp->height) pixmapy = 0; else pixmapy = (wp->height - pm->height) / 2; } else { /* GR_BACKGROUND_TILE (default)*/ GsWpTileBackgroundPixmap(wp, pm, x, y, width, height); return; } if(pm->width > wp->width) pmwidth = wp->width; else pmwidth = pm->width; if(pm->height > wp->height) pmheight = wp->height; else pmheight = pm->height; if(x > pixmapx) { destx = x; fromx = x - pixmapx; destwidth = pixmapx + pmwidth - x; } else { destx = pixmapx; fromx = 0; destwidth = x + width - pixmapx; } if(y > pixmapy) { desty = y; fromy = y - pixmapy; destheight = pixmapy + pmheight - desty; } else { desty = pixmapy; fromy = 0; destheight = y + height - pixmapy; } if(destwidth > 0 && destheight > 0) { if (wp->bgpixmapflags & GR_BACKGROUND_STRETCH) { GdStretchBlit(wp->psd, destx + wp->x, desty + wp->y, destwidth, destheight, pm->psd, fromx, fromy, pm->width, pm->height, MWROP_COPY); } else GdBlit(wp->psd, destx + wp->x, desty + wp->y, destwidth, destheight, pm->psd, fromx, fromy, MWROP_COPY); } if(wp->bgpixmapflags & (GR_BACKGROUND_TRANS|GR_BACKGROUND_STRETCH)) return; /* Fill in the gaps around the pixmap */ if(x < pixmapx) { fillwidth = pixmapx - x; if(fillwidth > width) fillwidth = width; fillheight = height; GdFillRect(wp->psd, wp->x + x, wp->y + y, fillwidth,fillheight); } if((x + width) > (pixmapx + pmwidth)) { fillwidth = (x + width) - (pixmapx + pmwidth); if(fillwidth > width) fillwidth = width; fillheight = height; if(x < (pixmapx + pmwidth)) destx = pixmapx + pmwidth + wp->x; else destx = x + wp->x; GdFillRect(wp->psd, destx, wp->y + y, fillwidth, fillheight); } if(y < pixmapy) { fillheight = pixmapy - y; if(fillheight > height) fillheight = height; if(x < pixmapx) destx = pixmapx + wp->x; else destx = x + wp->x; if((x + width) > (pixmapx + pmwidth)) fillwidth = pixmapx + pmwidth - destx; else fillwidth = x + width - destx;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -