📄 window.c
字号:
/* $XConsortium: window.c /main/210 1996/10/28 07:24:59 kaleb $ *//* $XFree86: xc/programs/Xserver/dix/window.c,v 3.6 1997/01/18 06:53:16 dawes Exp $ *//*Copyright (c) 1987 X ConsortiumPermission is hereby granted, free of charge, to any person obtaininga copy of this software and associated documentation files (the"Software"), to deal in the Software without restriction, includingwithout limitation the rights to use, copy, modify, merge, publish,distribute, sublicense, and/or sell copies of the Software, and topermit persons to whom the Software is furnished to do so, subject tothe following conditions:The above copyright notice and this permission notice shall be includedin all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OFMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OROTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OROTHER DEALINGS IN THE SOFTWARE.Except as contained in this notice, the name of the X Consortium shallnot be used in advertising or otherwise to promote the sale, use orother dealings in this Software without prior written authorizationfrom the X Consortium.Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, All Rights ReservedPermission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and thatboth that copyright notice and this permission notice appear in supporting documentation, and that the name of Digital not beused in advertising or publicity pertaining to distribution of thesoftware without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDINGALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALLDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ORANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THISSOFTWARE.*/#include "misc.h"#include "scrnintstr.h"#include "os.h"#include "regionstr.h"#include "validate.h"#include "windowstr.h"#include "input.h"#include "resource.h"#include "colormapst.h"#include "cursorstr.h"#include "dixstruct.h"#include "gcstruct.h"#include "servermd.h"#include "dixevents.h"#ifdef XAPPGROUP#include "extensions/Xagsrv.h"#endif#ifdef XCSECURITY#define _SECURITY_SERVER#include "extensions/security.h"#endifextern Bool permitOldBugs;#if defined(NEED_SCREEN_REGIONS)#define REGION_PTR(pScreen,pWin) \ register ScreenPtr pScreen = pWin->drawable.pScreen;#else#define REGION_PTR(pScreen,pWin) /* nothing */#endif/****** * Window stuff for server * * CreateRootWindow, CreateWindow, ChangeWindowAttributes, * GetWindowAttributes, DeleteWindow, DestroySubWindows, * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows, * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow, * ******/static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};int screenIsSaved = SCREEN_SAVER_OFF;ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];extern WindowPtr *WindowTable;extern int rand();static Bool TileScreenSaver(#if NeedFunctionPrototypes int /*i*/, int /*kind*/#endif);#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \ CWDontPropagate | CWOverrideRedirect | CWCursor )#define BOXES_OVERLAP(b1, b2) \ (!( ((b1)->x2 <= (b2)->x1) || \ ( ((b1)->x1 >= (b2)->x2)) || \ ( ((b1)->y2 <= (b2)->y1)) || \ ( ((b1)->y1 >= (b2)->y2)) ) )#define RedirectSend(pWin) \ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)#define SubSend(pWin) \ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)#define StrSend(pWin) \ ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))int numSaveUndersViewable = 0;int deltaSaveUndersViewable = 0;#ifdef DEBUG/****** * PrintWindowTree * For debugging only ******/intPrintChildren(p1, indent) WindowPtr p1; int indent;{ WindowPtr p2; int i; while (p1) { p2 = p1->firstChild; for (i=0; i<indent; i++) ErrorF( " "); ErrorF( "%x\n", p1->drawable.id); miPrintRegion(&p1->clipList); PrintChildren(p2, indent+4); p1 = p1->nextSib; }}PrintWindowTree(){ int i; WindowPtr pWin, p1; for (i=0; i<screenInfo.numScreens; i++) { ErrorF( "WINDOW %d\n", i); pWin = WindowTable[i]; miPrintRegion(&pWin->clipList); p1 = pWin->firstChild; PrintChildren(p1, 4); }}#endifintTraverseTree(pWin, func, data) register WindowPtr pWin; VisitWindowProcPtr func; pointer data;{ register int result; register WindowPtr pChild; if (!(pChild = pWin)) return(WT_NOMATCH); while (1) { result = (* func)(pChild, data); if (result == WT_STOPWALKING) return(WT_STOPWALKING); if ((result == WT_WALKCHILDREN) && pChild->firstChild) { pChild = pChild->firstChild; continue; } while (!pChild->nextSib && (pChild != pWin)) pChild = pChild->parent; if (pChild == pWin) break; pChild = pChild->nextSib; } return(WT_NOMATCH);}/***** * WalkTree * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on * each window. If FUNC returns WT_WALKCHILDREN, traverse the children, * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING * exit WalkTree. Does depth-first traverse. *****/intWalkTree(pScreen, func, data) ScreenPtr pScreen; VisitWindowProcPtr func; pointer data;{ return(TraverseTree(WindowTable[pScreen->myNum], func, data));}/* hack for forcing backing store on all windows */int defaultBackingStore = NotUseful;/* hack to force no backing store */Bool disableBackingStore = FALSE;/* hack to force no save unders */Bool disableSaveUnders = FALSE;static void#if NeedFunctionPrototypesSetWindowToDefaults(register WindowPtr pWin)#elseSetWindowToDefaults(pWin) register WindowPtr pWin;#endif{ pWin->prevSib = NullWindow; pWin->firstChild = NullWindow; pWin->lastChild = NullWindow; pWin->valdata = (ValidatePtr)NULL; pWin->optional = (WindowOptPtr)NULL; pWin->cursorIsNone = TRUE; pWin->backingStore = NotUseful; pWin->DIXsaveUnder = FALSE; pWin->backStorage = (pointer) NULL; pWin->mapped = FALSE; /* off */ pWin->realized = FALSE; /* off */ pWin->viewable = FALSE; pWin->visibility = VisibilityNotViewable; pWin->overrideRedirect = FALSE; pWin->saveUnder = FALSE; pWin->bitGravity = ForgetGravity; pWin->winGravity = NorthWestGravity; pWin->eventMask = 0; pWin->deliverableEvents = 0; pWin->dontPropagate = 0; pWin->forcedBS = FALSE;#ifdef NEED_DBE_BUF_BITS pWin->srcBuffer = DBE_FRONT_BUFFER; pWin->dstBuffer = DBE_FRONT_BUFFER;#endif}static void#if NeedFunctionPrototypesMakeRootTile(WindowPtr pWin)#elseMakeRootTile(pWin) WindowPtr pWin;#endif{ ScreenPtr pScreen = pWin->drawable.pScreen; GCPtr pGC; unsigned char back[128]; int len = BitmapBytePad(4); register unsigned char *from, *to; register int i, j; pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4, pScreen->rootDepth); pWin->backgroundState = BackgroundPixmap; pGC = GetScratchGC(pScreen->rootDepth, pScreen); if (!pWin->background.pixmap || !pGC) FatalError("cound not create root tile"); { CARD32 attributes[2]; attributes[0] = pScreen->whitePixel; attributes[1] = pScreen->blackPixel; (void)ChangeGC(pGC, GCForeground | GCBackground, attributes); } ValidateGC((DrawablePtr)pWin->background.pixmap, pGC); from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb; to = back; for (i = 4; i > 0; i--, from++) for (j = len; j > 0; j--) *to++ = *from; (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1, 0, 0, 4, 4, 0, XYBitmap, (char *)back); FreeScratchGC(pGC);}WindowPtrAllocateWindow(pScreen) ScreenPtr pScreen;{ WindowPtr pWin; register char *ptr; register DevUnion *ppriv; register unsigned *sizes; register unsigned size; register int i; pWin = (WindowPtr)xalloc(pScreen->totalWindowSize); if (pWin) { ppriv = (DevUnion *)(pWin + 1); pWin->devPrivates = ppriv; sizes = pScreen->WindowPrivateSizes; ptr = (char *)(ppriv + pScreen->WindowPrivateLen); for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++) { if ( (size = *sizes) ) { ppriv->ptr = (pointer)ptr; ptr += size; } else ppriv->ptr = (pointer)NULL; } } return pWin;}/***** * CreateRootWindow * Makes a window at initialization time for specified screen *****/BoolCreateRootWindow(pScreen) ScreenPtr pScreen;{ WindowPtr pWin; BoxRec box; PixmapFormatRec *format; pWin = AllocateWindow(pScreen); if (!pWin) return FALSE; savedScreenInfo[pScreen->myNum].pWindow = NULL; savedScreenInfo[pScreen->myNum].wid = FakeClientID(0); savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL; screenIsSaved = SCREEN_SAVER_OFF; WindowTable[pScreen->myNum] = pWin; pWin->drawable.pScreen = pScreen; pWin->drawable.type = DRAWABLE_WINDOW; pWin->drawable.depth = pScreen->rootDepth; for (format = screenInfo.formats; format->depth != pScreen->rootDepth; format++) ; pWin->drawable.bitsPerPixel = format->bitsPerPixel; pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; pWin->parent = NullWindow; SetWindowToDefaults(pWin); pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec)); pWin->optional->dontPropagateMask = 0; pWin->optional->otherEventMasks = 0; pWin->optional->otherClients = NULL; pWin->optional->passiveGrabs = NULL; pWin->optional->userProps = NULL; pWin->optional->backingBitPlanes = ~0L; pWin->optional->backingPixel = 0;#ifdef SHAPE pWin->optional->boundingShape = NULL; pWin->optional->clipShape = NULL;#endif#ifdef XINPUT pWin->optional->inputMasks = NULL;#endif pWin->optional->colormap = pScreen->defColormap; pWin->optional->visual = pScreen->rootVisual; pWin->nextSib = NullWindow; pWin->drawable.id = FakeClientID(0); pWin->origin.x = pWin->origin.y = 0; pWin->drawable.height = pScreen->height; pWin->drawable.width = pScreen->width; pWin->drawable.x = pWin->drawable.y = 0; box.x1 = 0; box.y1 = 0; box.x2 = pScreen->width; box.y2 = pScreen->height; REGION_INIT(pScreen, &pWin->clipList, &box, 1); REGION_INIT(pScreen, &pWin->winSize, &box, 1); REGION_INIT(pScreen, &pWin->borderSize, &box, 1); REGION_INIT(pScreen, &pWin->borderClip, &box, 1); pWin->drawable.class = InputOutput; pWin->optional->visual = pScreen->rootVisual; pWin->backgroundState = BackgroundPixel; pWin->background.pixel = pScreen->whitePixel; pWin->borderIsPixel = TRUE; pWin->border.pixel = pScreen->blackPixel; pWin->borderWidth = 0; if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin)) return FALSE; if (disableBackingStore) pScreen->backingStoreSupport = NotUseful;#ifdef DO_SAVE_UNDERS if ((pScreen->backingStoreSupport != NotUseful) && (pScreen->saveUnderSupport == NotUseful)) { /* * If the screen has backing-store but no save-unders, let the * clients know we can support save-unders using backing-store. */ pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS; }#endif /* DO_SAVE_UNDERS */ if (disableSaveUnders) pScreen->saveUnderSupport = NotUseful; return TRUE;}voidInitRootWindow(pWin) WindowPtr pWin;{ ScreenPtr pScreen; pScreen = pWin->drawable.pScreen; if (!(*pScreen->CreateWindow)(pWin)) return; /* XXX */ (*pScreen->PositionWindow)(pWin, 0, 0); pWin->cursorIsNone = FALSE; pWin->optional->cursor = rootCursor; rootCursor->refcnt++; MakeRootTile(pWin); pWin->backingStore = defaultBackingStore; pWin->forcedBS = (defaultBackingStore != NotUseful); /* We SHOULD check for an error value here XXX */ (*pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore); MapWindow(pWin, serverClient);}/* Set the region to the intersection of the rectangle and the * window's winSize. The window is typically the parent of the * window from which the region came. */voidClippedRegionFromBox(pWin, Rgn, x, y, w, h) register WindowPtr pWin; RegionPtr Rgn; register int x, y; int w, h;{ REGION_PTR(pScreen, pWin) BoxRec box; box = *(REGION_EXTENTS(pScreen, &pWin->winSize)); /* we do these calculations to avoid overflows */ if (x > box.x1) box.x1 = x; if (y > box.y1) box.y1 = y; x += w; if (x < box.x2) box.x2 = x; y += h; if (y < box.y2) box.y2 = y; if (box.x1 > box.x2) box.x2 = box.x1; if (box.y1 > box.y2) box.y2 = box.y1; REGION_RESET(pScreen, Rgn, &box);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -