123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363 |
- /*
- Copyright (c) 2006, Red Hat, Inc.
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- RED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of Red Hat shall not be
- used in advertising or otherwise to promote the sale, use or other dealings
- in this Software without prior written authorization from Red Hat.
- Copyright 1987, 1998 The Open Group
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of The Open Group shall
- not be used in advertising or otherwise to promote the sale, use or
- other dealings in this Software without prior written authorization
- from The Open Group.
- Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
- All Rights Reserved
- Permission 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 that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of Digital not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
- DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY 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 THIS
- SOFTWARE.
- */
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #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"
- #include "globals.h"
- /******
- * Window stuff for server
- *
- * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
- * GetWindowAttributes, DeleteWindow, DestroySubWindows,
- * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
- * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
- *
- ******/
- static const unsigned char _back_lsb[4] = { 0x88, 0x22, 0x44, 0x11 };
- static const unsigned char _back_msb[4] = { 0x11, 0x44, 0x22, 0x88 };
- _X_EXPORT int screenIsSaved = SCREEN_SAVER_OFF;
- _X_EXPORT ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
- static Bool TileScreenSaver(int i, int kind);
- #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))
- #ifdef DEBUG
- /******
- * PrintWindowTree
- * For debugging only
- ******/
- int
- PrintChildren(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);
- }
- }
- #endif
- _X_EXPORT int
- TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, pointer data)
- {
- int result;
- 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.
- *****/
- _X_EXPORT int
- WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
- {
- return (TraverseTree(WindowTable[pScreen->myNum], func, data));
- }
- /* hack for forcing backing store on all windows */
- static const int defaultBackingStore = NotUseful;
- static void
- SetWindowToDefaults(register WindowPtr pWin)
- {
- 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
- MakeRootTile(WindowPtr pWin)
- {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- GCPtr pGC;
- unsigned char back[128];
- int len = BitmapBytePad(sizeof(long));
- const unsigned char *from;
- unsigned char *to;
- 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("could 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, len, 4, 0, XYBitmap, (char *) back);
- FreeScratchGC(pGC);
- }
- WindowPtr
- AllocateWindow(ScreenPtr pScreen)
- {
- WindowPtr pWin;
- char *ptr;
- DevUnion *ppriv;
- unsigned *sizes;
- unsigned size;
- int i;
- pWin = malloc(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;
- }
- #if _XSERVER64
- pWin->drawable.pad0 = 0;
- pWin->drawable.pad1 = 0;
- #endif
- }
- return pWin;
- }
- /*****
- * CreateRootWindow
- * Makes a window at initialization time for specified screen
- *****/
- Bool
- CreateRootWindow(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 = malloc(sizeof(WindowOptRec));
- if (!pWin->optional)
- return FALSE;
- 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;
- pWin->optional->boundingShape = NULL;
- pWin->optional->clipShape = NULL;
- pWin->optional->inputShape = NULL;
- 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;
- BoxRec *boxptr = &box;
- REGION_INIT(&pWin->clipList, boxptr, 1);
- REGION_INIT(&pWin->winSize, boxptr, 1);
- REGION_INIT(&pWin->borderSize, boxptr, 1);
- REGION_INIT(&pWin->borderClip, boxptr, 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;
- pScreen->saveUnderSupport = NotUseful;
- return TRUE;
- }
- void
- InitRootWindow(WindowPtr pWin)
- {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- int backFlag = CWBorderPixel | CWCursor | CWBackingStore;
- if (!(*pScreen->CreateWindow) (pWin))
- return; /* XXX */
- (*pScreen->PositionWindow) (pWin, 0, 0);
- pWin->cursorIsNone = FALSE;
- pWin->optional->cursor = rootCursor;
- rootCursor->refcnt++;
- if (!blackRoot && !whiteRoot) {
- MakeRootTile(pWin);
- backFlag |= CWBackPixmap;
- }
- else {
- if (blackRoot)
- pWin->background.pixel = pScreen->blackPixel;
- else
- pWin->background.pixel = pScreen->whitePixel;
- backFlag |= CWBackPixel;
- }
- pWin->backingStore = defaultBackingStore;
- pWin->forcedBS = (defaultBackingStore != NotUseful);
- /* We SHOULD check for an error value here XXX */
- (*pScreen->ChangeWindowAttributes) (pWin, backFlag);
- 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.
- */
- void
- ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
- register int x, register int y,
- register int w, register int h)
- {
- BoxRec box;
- box = *(REGION_EXTENTS(&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(Rgn, &box);
- REGION_INTERSECT(Rgn, Rgn, &pWin->winSize);
- }
- static RealChildHeadProc realChildHeadProc = NULL;
- void
- RegisterRealChildHeadProc(RealChildHeadProc proc)
- {
- realChildHeadProc = proc;
- }
- WindowPtr
- RealChildHead(register WindowPtr pWin)
- {
- if (realChildHeadProc) {
- return realChildHeadProc(pWin);
- }
- if (!pWin->parent &&
- (screenIsSaved == SCREEN_SAVER_ON) &&
- (HasSaverWindow(pWin->drawable.pScreen->myNum)))
- return (pWin->firstChild);
- else
- return (NullWindow);
- }
- /*****
- * CreateWindow
- * Makes a window in response to client request
- *****/
- _X_EXPORT WindowPtr
- CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
- unsigned h, unsigned bw, unsigned class, register Mask vmask,
- XID *vlist, int depth, ClientPtr client, VisualID visual,
- int *error)
- {
- WindowPtr pWin;
- WindowPtr pHead;
- ScreenPtr pScreen;
- xEvent event;
- int idepth, ivisual;
- Bool fOK;
- DepthPtr pDepth;
- PixmapFormatRec *format;
- WindowOptPtr ancwopt;
- if (class == CopyFromParent)
- class = pParent->drawable.class;
- if ((class != InputOutput) && (class != InputOnly)) {
- *error = BadValue;
- client->errorValue = class;
- return NullWindow;
- }
- if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) {
- *error = BadMatch;
- return NullWindow;
- }
- if ((class == InputOnly) && ((bw != 0) || (depth != 0))) {
- *error = BadMatch;
- return NullWindow;
- }
- pScreen = pParent->drawable.pScreen;
- if ((class == InputOutput) && (depth == 0))
- depth = pParent->drawable.depth;
- ancwopt = pParent->optional;
- if (!ancwopt)
- ancwopt = FindWindowWithOptional(pParent)->optional;
- if (visual == CopyFromParent) {
- visual = ancwopt->visual;
- }
- /* Find out if the depth and visual are acceptable for this Screen */
- if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) {
- fOK = FALSE;
- for (idepth = 0; idepth < pScreen->numDepths; idepth++) {
- pDepth = (DepthPtr) & pScreen->allowedDepths[idepth];
- if ((depth == pDepth->depth) || (depth == 0)) {
- for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) {
- if (visual == pDepth->vids[ivisual]) {
- fOK = TRUE;
- break;
- }
- }
- }
- }
- if (fOK == FALSE) {
- *error = BadMatch;
- return NullWindow;
- }
- }
- if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
- (class != InputOnly) && (depth != pParent->drawable.depth)) {
- *error = BadMatch;
- return NullWindow;
- }
- if (((vmask & CWColormap) == 0) &&
- (class != InputOnly) &&
- ((visual != ancwopt->visual) || (ancwopt->colormap == None))) {
- *error = BadMatch;
- return NullWindow;
- }
- pWin = AllocateWindow(pScreen);
- if (!pWin) {
- *error = BadAlloc;
- return NullWindow;
- }
- pWin->drawable = pParent->drawable;
- pWin->drawable.depth = depth;
- if (depth == pParent->drawable.depth)
- pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
- else {
- for (format = screenInfo.formats; format->depth != depth; format++);
- pWin->drawable.bitsPerPixel = format->bitsPerPixel;
- }
- if (class == InputOnly)
- pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
- pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pWin->drawable.id = wid;
- pWin->drawable.class = class;
- pWin->parent = pParent;
- SetWindowToDefaults(pWin);
- if (visual != ancwopt->visual) {
- if (!MakeWindowOptional(pWin)) {
- free(pWin);
- *error = BadAlloc;
- return NullWindow;
- }
- pWin->optional->visual = visual;
- pWin->optional->colormap = None;
- }
- pWin->borderWidth = bw;
- pWin->backgroundState = None;
- pWin->borderIsPixel = pParent->borderIsPixel;
- pWin->border = pParent->border;
- if (pWin->borderIsPixel == FALSE)
- pWin->border.pixmap->refcnt++;
- pWin->origin.x = x + (int) bw;
- pWin->origin.y = y + (int) bw;
- pWin->drawable.width = w;
- pWin->drawable.height = h;
- pWin->drawable.x = pParent->drawable.x + x + (int) bw;
- pWin->drawable.y = pParent->drawable.y + y + (int) bw;
- /* set up clip list correctly for unobscured WindowPtr */
- REGION_NULL(&pWin->clipList);
- REGION_NULL(&pWin->borderClip);
- REGION_NULL(&pWin->winSize);
- REGION_NULL(&pWin->borderSize);
- pHead = RealChildHead(pParent);
- if (pHead) {
- pWin->nextSib = pHead->nextSib;
- if (pHead->nextSib)
- pHead->nextSib->prevSib = pWin;
- else
- pParent->lastChild = pWin;
- pHead->nextSib = pWin;
- pWin->prevSib = pHead;
- }
- else {
- pWin->nextSib = pParent->firstChild;
- if (pParent->firstChild)
- pParent->firstChild->prevSib = pWin;
- else
- pParent->lastChild = pWin;
- pParent->firstChild = pWin;
- }
- SetWinSize(pWin);
- SetBorderSize(pWin);
- /* We SHOULD check for an error value here XXX */
- if (!(*pScreen->CreateWindow) (pWin)) {
- *error = BadAlloc;
- DeleteWindow(pWin, None);
- return NullWindow;
- }
- /* We SHOULD check for an error value here XXX */
- (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y);
- if (!(vmask & CWEventMask))
- RecalculateDeliverableEvents(pWin);
- if (vmask)
- *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient(pWin));
- else
- *error = Success;
- if (*error != Success) {
- DeleteWindow(pWin, None);
- return NullWindow;
- }
- if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful)) {
- XID value = defaultBackingStore;
- (void) ChangeWindowAttributes(pWin, CWBackingStore, &value,
- wClient(pWin));
- pWin->forcedBS = TRUE;
- }
- if (SubSend(pParent)) {
- event.u.u.type = CreateNotify;
- event.u.createNotify.window = wid;
- event.u.createNotify.parent = pParent->drawable.id;
- event.u.createNotify.x = x;
- event.u.createNotify.y = y;
- event.u.createNotify.width = w;
- event.u.createNotify.height = h;
- event.u.createNotify.borderWidth = bw;
- event.u.createNotify.override = pWin->overrideRedirect;
- DeliverEvents(pParent, &event, 1, NullWindow);
- }
- return pWin;
- }
- static void
- FreeWindowResources(register WindowPtr pWin)
- {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DeleteWindowFromAnySaveSet(pWin);
- DeleteWindowFromAnySelections(pWin);
- DeleteWindowFromAnyEvents(pWin, TRUE);
- REGION_UNINIT(&pWin->clipList);
- REGION_UNINIT(&pWin->winSize);
- REGION_UNINIT(&pWin->borderClip);
- REGION_UNINIT(&pWin->borderSize);
- if (wBoundingShape(pWin))
- REGION_DESTROY(wBoundingShape(pWin));
- if (wClipShape(pWin))
- REGION_DESTROY(wClipShape(pWin));
- if (wInputShape(pWin))
- REGION_DESTROY(wInputShape(pWin));
- if (pWin->borderIsPixel == FALSE)
- (*pScreen->DestroyPixmap) (pWin->border.pixmap);
- if (pWin->backgroundState == BackgroundPixmap)
- (*pScreen->DestroyPixmap) (pWin->background.pixmap);
- DeleteAllWindowProperties(pWin);
- /* We SHOULD check for an error value here XXX */
- (*pScreen->DestroyWindow) (pWin);
- DisposeWindowOptional(pWin);
- }
- static void
- CrushTree(WindowPtr pWin)
- {
- WindowPtr pChild, pSib, pParent;
- UnrealizeWindowProcPtr UnrealizeWindow;
- xEvent event;
- if (!(pChild = pWin->firstChild))
- return;
- UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
- while (1) {
- if (pChild->firstChild) {
- pChild = pChild->firstChild;
- continue;
- }
- while (1) {
- pParent = pChild->parent;
- if (SubStrSend(pChild, pParent)) {
- event.u.u.type = DestroyNotify;
- event.u.destroyNotify.window = pChild->drawable.id;
- DeliverEvents(pChild, &event, 1, NullWindow);
- }
- FreeResource(pChild->drawable.id, RT_WINDOW);
- pSib = pChild->nextSib;
- pChild->viewable = FALSE;
- if (pChild->realized) {
- pChild->realized = FALSE;
- (*UnrealizeWindow) (pChild);
- }
- FreeWindowResources(pChild);
- free(pChild);
- if ((pChild = pSib))
- break;
- pChild = pParent;
- pChild->firstChild = NullWindow;
- pChild->lastChild = NullWindow;
- if (pChild == pWin)
- return;
- }
- }
- }
- /*****
- * DeleteWindow
- * Deletes child of window then window itself
- * If wid is None, don't send any events
- *****/
- int
- DeleteWindow(pointer value, XID wid)
- {
- WindowPtr pParent;
- WindowPtr pWin = (WindowPtr) value;
- xEvent event;
- UnmapWindow(pWin, FALSE);
- CrushTree(pWin);
- pParent = pWin->parent;
- if (wid && pParent && SubStrSend(pWin, pParent)) {
- event.u.u.type = DestroyNotify;
- event.u.destroyNotify.window = pWin->drawable.id;
- DeliverEvents(pWin, &event, 1, NullWindow);
- }
- FreeWindowResources(pWin);
- if (pParent) {
- if (pParent->firstChild == pWin)
- pParent->firstChild = pWin->nextSib;
- if (pParent->lastChild == pWin)
- pParent->lastChild = pWin->prevSib;
- if (pWin->nextSib)
- pWin->nextSib->prevSib = pWin->prevSib;
- if (pWin->prevSib)
- pWin->prevSib->nextSib = pWin->nextSib;
- }
- free(pWin);
- return Success;
- }
- void
- DestroySubwindows(register WindowPtr pWin, ClientPtr client)
- {
- /* XXX
- * The protocol is quite clear that each window should be
- * destroyed in turn, however, unmapping all of the first
- * eliminates most of the calls to ValidateTree. So,
- * this implementation is incorrect in that all of the
- * UnmapNotifies occur before all of the DestroyNotifies.
- * If you care, simply delete the call to UnmapSubwindows.
- */
- UnmapSubwindows(pWin);
- while (pWin->lastChild)
- FreeResource(pWin->lastChild->drawable.id, RT_NONE);
- }
- #define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
- ButtonReleaseMask | PointerMotionMask)
- /*****
- * ChangeWindowAttributes
- *
- * The value-mask specifies which attributes are to be changed; the
- * value-list contains one value for each one bit in the mask, from least
- * to most significant bit in the mask.
- *****/
- _X_EXPORT int
- ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist,
- ClientPtr client)
- {
- Mask index2;
- XID *pVlist;
- PixmapPtr pPixmap;
- Pixmap pixID;
- CursorPtr pCursor, pOldCursor;
- Cursor cursorID;
- WindowPtr pChild;
- Colormap cmap;
- ColormapPtr pCmap;
- xEvent xE;
- int result;
- ScreenPtr pScreen;
- Mask vmaskCopy = 0;
- Mask tmask;
- unsigned int val;
- int error;
- Bool checkOptional = FALSE;
- Bool borderRelative = FALSE;
- if ((pWin->drawable.class == InputOnly) &&
- (vmask & (~INPUTONLY_LEGAL_MASK)))
- return BadMatch;
- error = Success;
- pScreen = pWin->drawable.pScreen;
- pVlist = vlist;
- tmask = vmask;
- while (tmask) {
- index2 = (Mask) lowbit(tmask);
- tmask &= ~index2;
- switch (index2) {
- case CWBackPixmap:
- pixID = (Pixmap) * pVlist;
- pVlist++;
- if (pWin->backgroundState == ParentRelative)
- borderRelative = TRUE;
- if (pixID == None) {
- if (pWin->backgroundState == BackgroundPixmap)
- (*pScreen->DestroyPixmap) (pWin->background.pixmap);
- if (!pWin->parent)
- MakeRootTile(pWin);
- else
- pWin->backgroundState = None;
- }
- else if (pixID == ParentRelative) {
- if (pWin->parent &&
- pWin->drawable.depth != pWin->parent->drawable.depth) {
- error = BadMatch;
- goto PatchUp;
- }
- if (pWin->backgroundState == BackgroundPixmap)
- (*pScreen->DestroyPixmap) (pWin->background.pixmap);
- if (!pWin->parent)
- MakeRootTile(pWin);
- else
- pWin->backgroundState = ParentRelative;
- borderRelative = TRUE;
- /* Note that the parent's backgroundTile's refcnt is NOT
- * incremented. */
- }
- else {
- pPixmap = (PixmapPtr) SecurityLookupIDByType(client, pixID,
- RT_PIXMAP,
- SecurityReadAccess);
- if (pPixmap != (PixmapPtr) NULL) {
- if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
- (pPixmap->drawable.pScreen != pScreen)) {
- error = BadMatch;
- goto PatchUp;
- }
- if (pWin->backgroundState == BackgroundPixmap)
- (*pScreen->DestroyPixmap) (pWin->background.pixmap);
- pWin->backgroundState = BackgroundPixmap;
- pWin->background.pixmap = pPixmap;
- pPixmap->refcnt++;
- }
- else {
- error = BadPixmap;
- client->errorValue = pixID;
- goto PatchUp;
- }
- }
- break;
- case CWBackPixel:
- if (pWin->backgroundState == ParentRelative)
- borderRelative = TRUE;
- if (pWin->backgroundState == BackgroundPixmap)
- (*pScreen->DestroyPixmap) (pWin->background.pixmap);
- pWin->backgroundState = BackgroundPixel;
- pWin->background.pixel = (CARD32) *pVlist;
- /* background pixel overrides background pixmap,
- so don't let the ddx layer see both bits */
- vmaskCopy &= ~CWBackPixmap;
- pVlist++;
- break;
- case CWBorderPixmap:
- pixID = (Pixmap) * pVlist;
- pVlist++;
- if (pixID == CopyFromParent) {
- if (!pWin->parent ||
- (pWin->drawable.depth != pWin->parent->drawable.depth)) {
- error = BadMatch;
- goto PatchUp;
- }
- if (pWin->borderIsPixel == FALSE)
- (*pScreen->DestroyPixmap) (pWin->border.pixmap);
- pWin->border = pWin->parent->border;
- if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE) {
- index2 = CWBorderPixel;
- }
- else {
- pWin->parent->border.pixmap->refcnt++;
- }
- }
- else {
- pPixmap = (PixmapPtr) SecurityLookupIDByType(client, pixID,
- RT_PIXMAP,
- SecurityReadAccess);
- if (pPixmap) {
- if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
- (pPixmap->drawable.pScreen != pScreen)) {
- error = BadMatch;
- goto PatchUp;
- }
- if (pWin->borderIsPixel == FALSE)
- (*pScreen->DestroyPixmap) (pWin->border.pixmap);
- pWin->borderIsPixel = FALSE;
- pWin->border.pixmap = pPixmap;
- pPixmap->refcnt++;
- }
- else {
- error = BadPixmap;
- client->errorValue = pixID;
- goto PatchUp;
- }
- }
- break;
- case CWBorderPixel:
- if (pWin->borderIsPixel == FALSE)
- (*pScreen->DestroyPixmap) (pWin->border.pixmap);
- pWin->borderIsPixel = TRUE;
- pWin->border.pixel = (CARD32) *pVlist;
- /* border pixel overrides border pixmap,
- so don't let the ddx layer see both bits */
- vmaskCopy &= ~CWBorderPixmap;
- pVlist++;
- break;
- case CWBitGravity:
- val = (CARD8) *pVlist;
- pVlist++;
- if (val > StaticGravity) {
- error = BadValue;
- client->errorValue = val;
- goto PatchUp;
- }
- pWin->bitGravity = val;
- break;
- case CWWinGravity:
- val = (CARD8) *pVlist;
- pVlist++;
- if (val > StaticGravity) {
- error = BadValue;
- client->errorValue = val;
- goto PatchUp;
- }
- pWin->winGravity = val;
- break;
- case CWBackingStore:
- val = (CARD8) *pVlist;
- pVlist++;
- if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) {
- error = BadValue;
- client->errorValue = val;
- goto PatchUp;
- }
- pWin->backingStore = val;
- pWin->forcedBS = FALSE;
- break;
- case CWBackingPlanes:
- if (pWin->optional || ((CARD32) *pVlist != (CARD32) ~0L)) {
- if (!pWin->optional && !MakeWindowOptional(pWin)) {
- error = BadAlloc;
- goto PatchUp;
- }
- pWin->optional->backingBitPlanes = (CARD32) *pVlist;
- if ((CARD32) *pVlist == (CARD32) ~0L)
- checkOptional = TRUE;
- }
- pVlist++;
- break;
- case CWBackingPixel:
- if (pWin->optional || (CARD32) *pVlist) {
- if (!pWin->optional && !MakeWindowOptional(pWin)) {
- error = BadAlloc;
- goto PatchUp;
- }
- pWin->optional->backingPixel = (CARD32) *pVlist;
- if (!*pVlist)
- checkOptional = TRUE;
- }
- pVlist++;
- break;
- case CWSaveUnder:
- val = (BOOL) * pVlist;
- pVlist++;
- if ((val != xTrue) && (val != xFalse)) {
- error = BadValue;
- client->errorValue = val;
- goto PatchUp;
- }
- pWin->saveUnder = val;
- break;
- case CWEventMask:
- result = EventSelectForWindow(pWin, client, (Mask) *pVlist);
- if (result) {
- error = result;
- goto PatchUp;
- }
- pVlist++;
- break;
- case CWDontPropagate:
- result = EventSuppressForWindow(pWin, client, (Mask) *pVlist,
- &checkOptional);
- if (result) {
- error = result;
- goto PatchUp;
- }
- pVlist++;
- break;
- case CWOverrideRedirect:
- val = (BOOL) * pVlist;
- pVlist++;
- if ((val != xTrue) && (val != xFalse)) {
- error = BadValue;
- client->errorValue = val;
- goto PatchUp;
- }
- pWin->overrideRedirect = val;
- break;
- case CWColormap:
- cmap = (Colormap) * pVlist;
- pVlist++;
- if (cmap == CopyFromParent) {
- if (pWin->parent &&
- (!pWin->optional ||
- pWin->optional->visual == wVisual(pWin->parent))) {
- cmap = wColormap(pWin->parent);
- }
- else
- cmap = None;
- }
- if (cmap == None) {
- error = BadMatch;
- goto PatchUp;
- }
- pCmap = (ColormapPtr) SecurityLookupIDByType(client, cmap,
- RT_COLORMAP,
- SecurityReadAccess);
- if (!pCmap) {
- error = BadColor;
- client->errorValue = cmap;
- goto PatchUp;
- }
- if (pCmap->pVisual->vid != wVisual(pWin) ||
- pCmap->pScreen != pScreen) {
- error = BadMatch;
- goto PatchUp;
- }
- if (cmap != wColormap(pWin)) {
- if (!pWin->optional) {
- if (!MakeWindowOptional(pWin)) {
- error = BadAlloc;
- goto PatchUp;
- }
- }
- else if (pWin->parent && cmap == wColormap(pWin->parent))
- checkOptional = TRUE;
- /*
- * propagate the original colormap to any children
- * inheriting it
- */
- for (pChild = pWin->firstChild; pChild;
- pChild = pChild->nextSib) {
- if (!pChild->optional && !MakeWindowOptional(pChild)) {
- error = BadAlloc;
- goto PatchUp;
- }
- }
- pWin->optional->colormap = cmap;
- /*
- * check on any children now matching the new colormap
- */
- for (pChild = pWin->firstChild; pChild;
- pChild = pChild->nextSib) {
- if (pChild->optional->colormap == cmap)
- CheckWindowOptionalNeed(pChild);
- }
- xE.u.u.type = ColormapNotify;
- xE.u.colormap.window = pWin->drawable.id;
- xE.u.colormap.colormap = cmap;
- xE.u.colormap.new = xTrue;
- xE.u.colormap.state = IsMapInstalled(cmap, pWin);
- DeliverEvents(pWin, &xE, 1, NullWindow);
- }
- break;
- case CWCursor:
- cursorID = (Cursor) * pVlist;
- pVlist++;
- /*
- * install the new
- */
- if (cursorID == None) {
- if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
- pCursor = rootCursor;
- else
- pCursor = (CursorPtr) None;
- }
- else {
- pCursor = (CursorPtr) SecurityLookupIDByType(client, cursorID,
- RT_CURSOR,
- SecurityReadAccess);
- if (!pCursor) {
- error = BadCursor;
- client->errorValue = cursorID;
- goto PatchUp;
- }
- }
- if (pCursor != wCursor(pWin)) {
- /*
- * patch up child windows so they don't lose cursors.
- */
- for (pChild = pWin->firstChild; pChild;
- pChild = pChild->nextSib) {
- if (!pChild->optional && !pChild->cursorIsNone &&
- !MakeWindowOptional(pChild)) {
- error = BadAlloc;
- goto PatchUp;
- }
- }
- pOldCursor = 0;
- if (pCursor == (CursorPtr) None) {
- pWin->cursorIsNone = TRUE;
- if (pWin->optional) {
- pOldCursor = pWin->optional->cursor;
- pWin->optional->cursor = (CursorPtr) None;
- checkOptional = TRUE;
- }
- }
- else {
- if (!pWin->optional) {
- if (!MakeWindowOptional(pWin)) {
- error = BadAlloc;
- goto PatchUp;
- }
- }
- else if (pWin->parent && pCursor == wCursor(pWin->parent))
- checkOptional = TRUE;
- pOldCursor = pWin->optional->cursor;
- pWin->optional->cursor = pCursor;
- pCursor->refcnt++;
- pWin->cursorIsNone = FALSE;
- /*
- * check on any children now matching the new cursor
- */
- for (pChild = pWin->firstChild; pChild;
- pChild = pChild->nextSib) {
- if (pChild->optional &&
- (pChild->optional->cursor == pCursor))
- CheckWindowOptionalNeed(pChild);
- }
- }
- if (pWin->realized)
- WindowHasNewCursor(pWin);
- /* Can't free cursor until here - old cursor
- * is needed in WindowHasNewCursor
- */
- if (pOldCursor)
- FreeCursor(pOldCursor, (Cursor) 0);
- }
- break;
- default:
- error = BadValue;
- client->errorValue = vmask;
- goto PatchUp;
- }
- vmaskCopy |= index2;
- }
- PatchUp:
- if (checkOptional)
- CheckWindowOptionalNeed(pWin);
- /* We SHOULD check for an error value here XXX */
- (*pScreen->ChangeWindowAttributes) (pWin, vmaskCopy);
- /*
- If the border contents have changed, redraw the border.
- Note that this has to be done AFTER pScreen->ChangeWindowAttributes
- for the tile to be rotated, and the correct function selected.
- */
- if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
- && pWin->viewable && HasBorder(pWin)) {
- RegionRec exposed;
- REGION_NULL(&exposed);
- REGION_SUBTRACT(&exposed, &pWin->borderClip, &pWin->winSize);
- (*pWin->drawable.pScreen->PaintWindowBorder) (pWin, &exposed,
- PW_BORDER);
- REGION_UNINIT(&exposed);
- }
- return error;
- }
- /*****
- * GetWindowAttributes
- * Notice that this is different than ChangeWindowAttributes
- *****/
- void
- GetWindowAttributes(register WindowPtr pWin, ClientPtr client,
- xGetWindowAttributesReply * wa)
- {
- wa->type = X_Reply;
- wa->bitGravity = pWin->bitGravity;
- wa->winGravity = pWin->winGravity;
- if (pWin->forcedBS && pWin->backingStore != Always)
- wa->backingStore = NotUseful;
- else
- wa->backingStore = pWin->backingStore;
- wa->length = (sizeof(xGetWindowAttributesReply) -
- sizeof(xGenericReply)) >> 2;
- wa->sequenceNumber = client->sequence;
- wa->backingBitPlanes = wBackingBitPlanes(pWin);
- wa->backingPixel = wBackingPixel(pWin);
- wa->saveUnder = (BOOL) pWin->saveUnder;
- wa->override = pWin->overrideRedirect;
- if (!pWin->mapped)
- wa->mapState = IsUnmapped;
- else if (pWin->realized)
- wa->mapState = IsViewable;
- else
- wa->mapState = IsUnviewable;
- wa->colormap = wColormap(pWin);
- wa->mapInstalled = (wa->colormap == None) ? xFalse
- : IsMapInstalled(wa->colormap, pWin);
- wa->yourEventMask = EventMaskForClient(pWin, client);
- wa->allEventMasks = pWin->eventMask | wOtherEventMasks(pWin);
- wa->doNotPropagateMask = wDontPropagateMask(pWin);
- wa->class = pWin->drawable.class;
- wa->visualID = wVisual(pWin);
- }
- _X_EXPORT WindowPtr
- MoveWindowInStack(register WindowPtr pWin, register WindowPtr pNextSib)
- {
- WindowPtr pParent = pWin->parent;
- WindowPtr pFirstChange = pWin; /* highest window where list changes */
- if (pWin->nextSib != pNextSib) {
- WindowPtr pOldNextSib = pWin->nextSib;
- if (!pNextSib) { /* move to bottom */
- if (pParent->firstChild == pWin)
- pParent->firstChild = pWin->nextSib;
- /* if (pWin->nextSib) *//* is always True: pNextSib == NULL
- * and pWin->nextSib != pNextSib
- * therefore pWin->nextSib != NULL */
- pFirstChange = pWin->nextSib;
- pWin->nextSib->prevSib = pWin->prevSib;
- if (pWin->prevSib)
- pWin->prevSib->nextSib = pWin->nextSib;
- pParent->lastChild->nextSib = pWin;
- pWin->prevSib = pParent->lastChild;
- pWin->nextSib = NullWindow;
- pParent->lastChild = pWin;
- }
- else if (pParent->firstChild == pNextSib) { /* move to top */
- pFirstChange = pWin;
- if (pParent->lastChild == pWin)
- pParent->lastChild = pWin->prevSib;
- if (pWin->nextSib)
- pWin->nextSib->prevSib = pWin->prevSib;
- if (pWin->prevSib)
- pWin->prevSib->nextSib = pWin->nextSib;
- pWin->nextSib = pParent->firstChild;
- pWin->prevSib = (WindowPtr) NULL;
- pNextSib->prevSib = pWin;
- pParent->firstChild = pWin;
- }
- else { /* move in middle of list */
- WindowPtr pOldNext = pWin->nextSib;
- pFirstChange = NullWindow;
- if (pParent->firstChild == pWin)
- pFirstChange = pParent->firstChild = pWin->nextSib;
- if (pParent->lastChild == pWin) {
- pFirstChange = pWin;
- pParent->lastChild = pWin->prevSib;
- }
- if (pWin->nextSib)
- pWin->nextSib->prevSib = pWin->prevSib;
- if (pWin->prevSib)
- pWin->prevSib->nextSib = pWin->nextSib;
- pWin->nextSib = pNextSib;
- pWin->prevSib = pNextSib->prevSib;
- if (pNextSib->prevSib)
- pNextSib->prevSib->nextSib = pWin;
- pNextSib->prevSib = pWin;
- if (!pFirstChange) { /* do we know it yet? */
- pFirstChange = pParent->firstChild; /* no, search from top */
- while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
- pFirstChange = pFirstChange->nextSib;
- }
- }
- if (pWin->drawable.pScreen->RestackWindow)
- (*pWin->drawable.pScreen->RestackWindow) (pWin, pOldNextSib);
- }
- return (pFirstChange);
- }
- _X_EXPORT void
- SetWinSize(register WindowPtr pWin)
- {
- ClippedRegionFromBox(pWin->parent, &pWin->winSize,
- pWin->drawable.x, pWin->drawable.y,
- (int) pWin->drawable.width,
- (int) pWin->drawable.height);
- if (wBoundingShape(pWin) || wClipShape(pWin)) {
- REGION_TRANSLATE(&pWin->winSize, -pWin->drawable.x,
- -pWin->drawable.y);
- if (wBoundingShape(pWin))
- REGION_INTERSECT(&pWin->winSize, &pWin->winSize,
- wBoundingShape(pWin));
- if (wClipShape(pWin))
- REGION_INTERSECT(&pWin->winSize, &pWin->winSize,
- wClipShape(pWin));
- REGION_TRANSLATE(&pWin->winSize, pWin->drawable.x,
- pWin->drawable.y);
- }
- }
- _X_EXPORT void
- SetBorderSize(register WindowPtr pWin)
- {
- int bw;
- if (HasBorder(pWin)) {
- bw = wBorderWidth(pWin);
- ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
- pWin->drawable.x - bw, pWin->drawable.y - bw,
- (int) (pWin->drawable.width + (bw << 1)),
- (int) (pWin->drawable.height + (bw << 1)));
- if (wBoundingShape(pWin)) {
- REGION_TRANSLATE(&pWin->borderSize, -pWin->drawable.x,
- -pWin->drawable.y);
- REGION_INTERSECT(&pWin->borderSize, &pWin->borderSize,
- wBoundingShape(pWin));
- REGION_TRANSLATE(&pWin->borderSize, pWin->drawable.x,
- pWin->drawable.y);
- REGION_UNION(&pWin->borderSize, &pWin->borderSize,
- &pWin->winSize);
- }
- }
- else {
- REGION_COPY(&pWin->borderSize, &pWin->winSize);
- }
- }
- /**
- *
- * \param x,y new window position
- * \param oldx,oldy old window position
- * \param destx,desty position relative to gravity
- */
- _X_EXPORT void
- GravityTranslate(register int x, register int y, int oldx, int oldy,
- int dw, int dh, unsigned gravity,
- register int *destx, register int *desty)
- {
- switch (gravity) {
- case NorthGravity:
- *destx = x + dw / 2;
- *desty = y;
- break;
- case NorthEastGravity:
- *destx = x + dw;
- *desty = y;
- break;
- case WestGravity:
- *destx = x;
- *desty = y + dh / 2;
- break;
- case CenterGravity:
- *destx = x + dw / 2;
- *desty = y + dh / 2;
- break;
- case EastGravity:
- *destx = x + dw;
- *desty = y + dh / 2;
- break;
- case SouthWestGravity:
- *destx = x;
- *desty = y + dh;
- break;
- case SouthGravity:
- *destx = x + dw / 2;
- *desty = y + dh;
- break;
- case SouthEastGravity:
- *destx = x + dw;
- *desty = y + dh;
- break;
- case StaticGravity:
- *destx = oldx;
- *desty = oldy;
- break;
- default:
- *destx = x;
- *desty = y;
- break;
- }
- }
- /* XXX need to retile border on each window with ParentRelative origin */
- _X_EXPORT void
- ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
- {
- ScreenPtr pScreen;
- WindowPtr pSib, pChild;
- Bool resized = (dw || dh);
- pScreen = pWin->drawable.pScreen;
- for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib) {
- if (resized && (pSib->winGravity > NorthWestGravity)) {
- int cwsx, cwsy;
- cwsx = pSib->origin.x;
- cwsy = pSib->origin.y;
- GravityTranslate(cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
- pSib->winGravity, &cwsx, &cwsy);
- if (cwsx != pSib->origin.x || cwsy != pSib->origin.y) {
- xEvent event;
- event.u.u.type = GravityNotify;
- event.u.gravity.window = pSib->drawable.id;
- event.u.gravity.x = cwsx - wBorderWidth(pSib);
- event.u.gravity.y = cwsy - wBorderWidth(pSib);
- DeliverEvents(pSib, &event, 1, NullWindow);
- pSib->origin.x = cwsx;
- pSib->origin.y = cwsy;
- }
- }
- pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
- pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
- SetWinSize(pSib);
- SetBorderSize(pSib);
- (*pScreen->PositionWindow) (pSib, pSib->drawable.x, pSib->drawable.y);
- if ((pChild = pSib->firstChild)) {
- while (1) {
- pChild->drawable.x = pChild->parent->drawable.x +
- pChild->origin.x;
- pChild->drawable.y = pChild->parent->drawable.y +
- pChild->origin.y;
- SetWinSize(pChild);
- SetBorderSize(pChild);
- (*pScreen->PositionWindow) (pChild,
- pChild->drawable.x,
- pChild->drawable.y);
- if (pChild->firstChild) {
- pChild = pChild->firstChild;
- continue;
- }
- while (!pChild->nextSib && (pChild != pSib))
- pChild = pChild->parent;
- if (pChild == pSib)
- break;
- pChild = pChild->nextSib;
- }
- }
- }
- }
- #define GET_INT16(m, f) \
- if (m & mask) \
- { \
- f = (INT16) *pVlist;\
- pVlist++; \
- }
- #define GET_CARD16(m, f) \
- if (m & mask) \
- { \
- f = (CARD16) *pVlist;\
- pVlist++;\
- }
- #define GET_CARD8(m, f) \
- if (m & mask) \
- { \
- f = (CARD8) *pVlist;\
- pVlist++;\
- }
- #define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
- #define IllegalInputOnlyConfigureMask (CWBorderWidth)
- /*
- * IsSiblingAboveMe
- * returns Above if pSib above pMe in stack or Below otherwise
- */
- static int
- IsSiblingAboveMe(register WindowPtr pMe, register WindowPtr pSib)
- {
- WindowPtr pWin;
- pWin = pMe->parent->firstChild;
- while (pWin) {
- if (pWin == pSib)
- return (Above);
- else if (pWin == pMe)
- return (Below);
- pWin = pWin->nextSib;
- }
- return (Below);
- }
- static BoxPtr
- WindowExtents(register WindowPtr pWin, register BoxPtr pBox)
- {
- pBox->x1 = pWin->drawable.x - wBorderWidth(pWin);
- pBox->y1 = pWin->drawable.y - wBorderWidth(pWin);
- pBox->x2 = pWin->drawable.x + (int) pWin->drawable.width
- + wBorderWidth(pWin);
- pBox->y2 = pWin->drawable.y + (int) pWin->drawable.height
- + wBorderWidth(pWin);
- return (pBox);
- }
- #define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
- static RegionPtr
- MakeBoundingRegion(register WindowPtr pWin, BoxPtr pBox)
- {
- RegionPtr pRgn;
- pRgn = REGION_CREATE(pBox, 1);
- if (wBoundingShape(pWin)) {
- REGION_TRANSLATE(pRgn, -pWin->origin.x, -pWin->origin.y);
- REGION_INTERSECT(pRgn, pRgn, wBoundingShape(pWin));
- REGION_TRANSLATE(pRgn, pWin->origin.x, pWin->origin.y);
- }
- return pRgn;
- }
- static Bool
- ShapeOverlap(WindowPtr pWin, BoxPtr pWinBox, WindowPtr pSib, BoxPtr pSibBox)
- {
- RegionPtr pWinRgn, pSibRgn;
- Bool ret;
- if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
- return TRUE;
- pWinRgn = MakeBoundingRegion(pWin, pWinBox);
- pSibRgn = MakeBoundingRegion(pSib, pSibBox);
- REGION_INTERSECT(pWinRgn, pWinRgn, pSibRgn);
- ret = REGION_NOTEMPTY(pWinRgn);
- REGION_DESTROY(pWinRgn);
- REGION_DESTROY(pSibRgn);
- return ret;
- }
- static Bool
- AnyWindowOverlapsMe(WindowPtr pWin, WindowPtr pHead, register BoxPtr box)
- {
- WindowPtr pSib;
- BoxRec sboxrec;
- BoxPtr sbox;
- for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib) {
- if (pSib->mapped) {
- sbox = WindowExtents(pSib, &sboxrec);
- if (BOXES_OVERLAP(sbox, box)
- && ShapeOverlap(pWin, box, pSib, sbox)
- )
- return (TRUE);
- }
- }
- return (FALSE);
- }
- static Bool
- IOverlapAnyWindow(WindowPtr pWin, register BoxPtr box)
- {
- WindowPtr pSib;
- BoxRec sboxrec;
- BoxPtr sbox;
- for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib) {
- if (pSib->mapped) {
- sbox = WindowExtents(pSib, &sboxrec);
- if (BOXES_OVERLAP(sbox, box)
- && ShapeOverlap(pWin, box, pSib, sbox)
- )
- return (TRUE);
- }
- }
- return (FALSE);
- }
- /*
- * WhereDoIGoInTheStack()
- * Given pWin and pSib and the relationshipe smode, return
- * the window that pWin should go ABOVE.
- * If a pSib is specified:
- * Above: pWin is placed just above pSib
- * Below: pWin is placed just below pSib
- * TopIf: if pSib occludes pWin, then pWin is placed
- * at the top of the stack
- * BottomIf: if pWin occludes pSib, then pWin is
- * placed at the bottom of the stack
- * Opposite: if pSib occludes pWin, then pWin is placed at the
- * top of the stack, else if pWin occludes pSib, then
- * pWin is placed at the bottom of the stack
- *
- * If pSib is NULL:
- * Above: pWin is placed at the top of the stack
- * Below: pWin is placed at the bottom of the stack
- * TopIf: if any sibling occludes pWin, then pWin is placed at
- * the top of the stack
- * BottomIf: if pWin occludes any sibline, then pWin is placed at
- * the bottom of the stack
- * Opposite: if any sibling occludes pWin, then pWin is placed at
- * the top of the stack, else if pWin occludes any
- * sibling, then pWin is placed at the bottom of the stack
- *
- */
- static WindowPtr
- WhereDoIGoInTheStack(register WindowPtr pWin,
- register WindowPtr pSib,
- short x,
- short y, unsigned short w, unsigned short h, int smode)
- {
- BoxRec box;
- WindowPtr pHead, pFirst;
- if ((pWin == pWin->parent->firstChild) && (pWin == pWin->parent->lastChild))
- return ((WindowPtr) NULL);
- pHead = RealChildHead(pWin->parent);
- pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
- box.x1 = x;
- box.y1 = y;
- box.x2 = x + (int) w;
- box.y2 = y + (int) h;
- switch (smode) {
- case Above:
- if (pSib)
- return (pSib);
- else if (pWin == pFirst)
- return (pWin->nextSib);
- else
- return (pFirst);
- case Below:
- if (pSib)
- if (pSib->nextSib != pWin)
- return (pSib->nextSib);
- else
- return (pWin->nextSib);
- else
- return NullWindow;
- case TopIf:
- if ((!pWin->mapped || (pSib && !pSib->mapped)))
- return (pWin->nextSib);
- else if (pSib) {
- if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
- (RECT_IN_REGION(&pSib->borderSize, &box) != rgnOUT))
- return (pFirst);
- else
- return (pWin->nextSib);
- }
- else if (AnyWindowOverlapsMe(pWin, pHead, &box))
- return (pFirst);
- else
- return (pWin->nextSib);
- case BottomIf:
- if ((!pWin->mapped || (pSib && !pSib->mapped)))
- return (pWin->nextSib);
- else if (pSib) {
- if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
- (RECT_IN_REGION(&pSib->borderSize, &box) != rgnOUT))
- return NullWindow;
- else
- return (pWin->nextSib);
- }
- else if (IOverlapAnyWindow(pWin, &box))
- return NullWindow;
- else
- return (pWin->nextSib);
- case Opposite:
- if ((!pWin->mapped || (pSib && !pSib->mapped)))
- return (pWin->nextSib);
- else if (pSib) {
- if (RECT_IN_REGION(&pSib->borderSize, &box) != rgnOUT) {
- if (IsSiblingAboveMe(pWin, pSib) == Above)
- return (pFirst);
- else
- return NullWindow;
- }
- else
- return (pWin->nextSib);
- }
- else if (AnyWindowOverlapsMe(pWin, pHead, &box)) {
- /* If I'm occluded, I can't possibly be the first child
- * if (pWin == pWin->parent->firstChild)
- * return pWin->nextSib;
- */
- return (pFirst);
- }
- else if (IOverlapAnyWindow(pWin, &box))
- return NullWindow;
- else
- return pWin->nextSib;
- default:
- {
- ErrorF("Internal error in ConfigureWindow, smode == %d\n", smode);
- return pWin->nextSib;
- }
- }
- }
- static void
- ReflectStackChange(register WindowPtr pWin,
- register WindowPtr pSib, VTKind kind)
- {
- /* Note that pSib might be NULL */
- Bool WasViewable = (Bool) pWin->viewable;
- Bool anyMarked;
- WindowPtr pFirstChange;
- WindowPtr pLayerWin;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- /* if this is a root window, can't be restacked */
- if (!pWin->parent)
- return;
- pFirstChange = MoveWindowInStack(pWin, pSib);
- if (WasViewable) {
- anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange,
- &pLayerWin);
- if (pLayerWin != pWin)
- pFirstChange = pLayerWin;
- if (anyMarked) {
- (*pScreen->ValidateTree) (pLayerWin->parent, pFirstChange, kind);
- (*pScreen->HandleExposures) (pLayerWin->parent);
- }
- if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
- (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstChange,
- kind);
- }
- if (pWin->realized)
- WindowsRestructured();
- }
- /*****
- * ConfigureWindow
- *****/
- int
- ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist,
- ClientPtr client)
- {
- #define RESTACK_WIN 0
- #define MOVE_WIN 1
- #define RESIZE_WIN 2
- #define REBORDER_WIN 3
- WindowPtr pSib = NullWindow;
- WindowPtr pParent = pWin->parent;
- Window sibwid = 0;
- Mask index2, tmask;
- XID *pVlist;
- short x, y, beforeX, beforeY;
- unsigned short w = pWin->drawable.width,
- h = pWin->drawable.height, bw = pWin->borderWidth;
- int action, smode = Above;
- xEvent event;
- if ((pWin->drawable.class == InputOnly) &&
- (mask & IllegalInputOnlyConfigureMask))
- return (BadMatch);
- if ((mask & CWSibling) && !(mask & CWStackMode))
- return (BadMatch);
- pVlist = vlist;
- if (pParent) {
- x = pWin->drawable.x - pParent->drawable.x - (int) bw;
- y = pWin->drawable.y - pParent->drawable.y - (int) bw;
- }
- else {
- x = pWin->drawable.x;
- y = pWin->drawable.y;
- }
- beforeX = x;
- beforeY = y;
- action = RESTACK_WIN;
- if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth)))) {
- GET_INT16(CWX, x);
- GET_INT16(CWY, y);
- action = MOVE_WIN;
- }
- /* or should be resized */
- else if (mask & (CWX | CWY | CWWidth | CWHeight)) {
- GET_INT16(CWX, x);
- GET_INT16(CWY, y);
- GET_CARD16(CWWidth, w);
- GET_CARD16(CWHeight, h);
- if (!w || !h) {
- client->errorValue = 0;
- return BadValue;
- }
- action = RESIZE_WIN;
- }
- tmask = mask & ~ChangeMask;
- while (tmask) {
- index2 = (Mask) lowbit(tmask);
- tmask &= ~index2;
- switch (index2) {
- case CWBorderWidth:
- GET_CARD16(CWBorderWidth, bw);
- break;
- case CWSibling:
- sibwid = (Window) *pVlist;
- pVlist++;
- pSib = (WindowPtr) SecurityLookupIDByType(client, sibwid,
- RT_WINDOW,
- SecurityReadAccess);
- if (!pSib) {
- client->errorValue = sibwid;
- return (BadWindow);
- }
- if (pSib->parent != pParent)
- return (BadMatch);
- if (pSib == pWin)
- return (BadMatch);
- break;
- case CWStackMode:
- GET_CARD8(CWStackMode, smode);
- if ((smode != TopIf) && (smode != BottomIf) &&
- (smode != Opposite) && (smode != Above) && (smode != Below)) {
- client->errorValue = smode;
- return (BadValue);
- }
- break;
- default:
- client->errorValue = mask;
- return (BadValue);
- }
- }
- /* root really can't be reconfigured, so just return */
- if (!pParent)
- return Success;
- /* Figure out if the window should be moved. Doesnt
- make the changes to the window if event sent */
- if (mask & CWStackMode)
- pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
- pParent->drawable.y + y,
- w + (bw << 1), h + (bw << 1), smode);
- else
- pSib = pWin->nextSib;
- if ((!pWin->overrideRedirect) && (RedirectSend(pParent)
- )) {
- event.u.u.type = ConfigureRequest;
- event.u.configureRequest.window = pWin->drawable.id;
- if (mask & CWSibling)
- event.u.configureRequest.sibling = sibwid;
- else
- event.u.configureRequest.sibling = None;
- if (mask & CWStackMode)
- event.u.u.detail = smode;
- else
- event.u.u.detail = Above;
- event.u.configureRequest.x = x;
- event.u.configureRequest.y = y;
- event.u.configureRequest.width = w;
- event.u.configureRequest.height = h;
- event.u.configureRequest.borderWidth = bw;
- event.u.configureRequest.valueMask = mask;
- event.u.configureRequest.parent = pParent->drawable.id;
- if (MaybeDeliverEventsToClient(pParent, &event, 1,
- SubstructureRedirectMask, client) == 1)
- return (Success);
- }
- if (action == RESIZE_WIN) {
- Bool size_change = (w != pWin->drawable.width)
- || (h != pWin->drawable.height);
- if (size_change &&
- ((pWin->eventMask | wOtherEventMasks(pWin)) & ResizeRedirectMask)) {
- xEvent eventT;
- eventT.u.u.type = ResizeRequest;
- eventT.u.resizeRequest.window = pWin->drawable.id;
- eventT.u.resizeRequest.width = w;
- eventT.u.resizeRequest.height = h;
- if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
- ResizeRedirectMask, client) == 1) {
- /* if event is delivered, leave the actual size alone. */
- w = pWin->drawable.width;
- h = pWin->drawable.height;
- size_change = FALSE;
- }
- }
- if (!size_change) {
- if (mask & (CWX | CWY))
- action = MOVE_WIN;
- else if (mask & (CWStackMode | CWBorderWidth))
- action = RESTACK_WIN;
- else /* really nothing to do */
- return (Success);
- }
- }
- if (action == RESIZE_WIN)
- /* we've already checked whether there's really a size change */
- goto ActuallyDoSomething;
- if ((mask & CWX) && (x != beforeX))
- goto ActuallyDoSomething;
- if ((mask & CWY) && (y != beforeY))
- goto ActuallyDoSomething;
- if ((mask & CWBorderWidth) && (bw != wBorderWidth(pWin)))
- goto ActuallyDoSomething;
- if (mask & CWStackMode) {
- /* See above for why we always reorder in rootless mode. */
- if (pWin->nextSib != pSib)
- goto ActuallyDoSomething;
- }
- return (Success);
- ActuallyDoSomething:
- if (SubStrSend(pWin, pParent)) {
- event.u.u.type = ConfigureNotify;
- event.u.configureNotify.window = pWin->drawable.id;
- if (pSib)
- event.u.configureNotify.aboveSibling = pSib->drawable.id;
- else
- event.u.configureNotify.aboveSibling = None;
- event.u.configureNotify.x = x;
- event.u.configureNotify.y = y;
- event.u.configureNotify.width = w;
- event.u.configureNotify.height = h;
- event.u.configureNotify.borderWidth = bw;
- event.u.configureNotify.override = pWin->overrideRedirect;
- DeliverEvents(pWin, &event, 1, NullWindow);
- }
- if (mask & CWBorderWidth) {
- if (action == RESTACK_WIN) {
- action = MOVE_WIN;
- pWin->borderWidth = bw;
- }
- else if ((action == MOVE_WIN) &&
- (beforeX + wBorderWidth(pWin) == x + (int) bw) &&
- (beforeY + wBorderWidth(pWin) == y + (int) bw)) {
- action = REBORDER_WIN;
- (*pWin->drawable.pScreen->ChangeBorderWidth) (pWin, bw);
- }
- else
- pWin->borderWidth = bw;
- }
- if (action == MOVE_WIN)
- (*pWin->drawable.pScreen->MoveWindow) (pWin, x, y, pSib,
- (mask & CWBorderWidth) ? VTOther
- : VTMove);
- else if (action == RESIZE_WIN)
- (*pWin->drawable.pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
- else if (mask & CWStackMode)
- ReflectStackChange(pWin, pSib, VTOther);
- if (action != RESTACK_WIN)
- CheckCursorConfinement(pWin);
- return (Success);
- #undef RESTACK_WIN
- #undef MOVE_WIN
- #undef RESIZE_WIN
- #undef REBORDER_WIN
- }
- /******
- *
- * CirculateWindow
- * For RaiseLowest, raises the lowest mapped child (if any) that is
- * obscured by another child to the top of the stack. For LowerHighest,
- * lowers the highest mapped child (if any) that is obscuring another
- * child to the bottom of the stack. Exposure processing is performed
- *
- ******/
- int
- CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
- {
- WindowPtr pWin, pHead, pFirst;
- xEvent event;
- BoxRec box;
- pHead = RealChildHead(pParent);
- pFirst = pHead ? pHead->nextSib : pParent->firstChild;
- if (direction == RaiseLowest) {
- for (pWin = pParent->lastChild;
- (pWin != pHead) &&
- !(pWin->mapped &&
- AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
- pWin = pWin->prevSib);
- if (pWin == pHead)
- return Success;
- }
- else {
- for (pWin = pFirst;
- pWin &&
- !(pWin->mapped &&
- IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
- pWin = pWin->nextSib);
- if (!pWin)
- return Success;
- }
- event.u.circulate.window = pWin->drawable.id;
- event.u.circulate.parent = pParent->drawable.id;
- event.u.circulate.event = pParent->drawable.id;
- if (direction == RaiseLowest)
- event.u.circulate.place = PlaceOnTop;
- else
- event.u.circulate.place = PlaceOnBottom;
- if (RedirectSend(pParent)) {
- event.u.u.type = CirculateRequest;
- if (MaybeDeliverEventsToClient(pParent, &event, 1,
- SubstructureRedirectMask, client) == 1)
- return (Success);
- }
- event.u.u.type = CirculateNotify;
- DeliverEvents(pWin, &event, 1, NullWindow);
- ReflectStackChange(pWin,
- (direction == RaiseLowest) ? pFirst : NullWindow,
- VTStack);
- return (Success);
- }
- static int
- CompareWIDs(WindowPtr pWin, pointer value)
- { /* must conform to VisitWindowProcPtr */
- Window *wid = (Window *) value;
- if (pWin->drawable.id == *wid)
- return (WT_STOPWALKING);
- else
- return (WT_WALKCHILDREN);
- }
- /*****
- * ReparentWindow
- *****/
- int
- ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
- int x, int y, ClientPtr client)
- {
- WindowPtr pPrev, pPriorParent;
- Bool WasMapped = (Bool) (pWin->mapped);
- xEvent event;
- int bw = wBorderWidth(pWin);
- ScreenPtr pScreen;
- pScreen = pWin->drawable.pScreen;
- if (TraverseTree(pWin, CompareWIDs, (pointer) &pParent->drawable.id) ==
- WT_STOPWALKING)
- return (BadMatch);
- if (!MakeWindowOptional(pWin))
- return (BadAlloc);
- if (WasMapped)
- UnmapWindow(pWin, FALSE);
- event.u.u.type = ReparentNotify;
- event.u.reparent.window = pWin->drawable.id;
- event.u.reparent.parent = pParent->drawable.id;
- event.u.reparent.x = x;
- event.u.reparent.y = y;
- event.u.reparent.override = pWin->overrideRedirect;
- DeliverEvents(pWin, &event, 1, pParent);
- /* take out of sibling chain */
- pPriorParent = pPrev = pWin->parent;
- if (pPrev->firstChild == pWin)
- pPrev->firstChild = pWin->nextSib;
- if (pPrev->lastChild == pWin)
- pPrev->lastChild = pWin->prevSib;
- if (pWin->nextSib)
- pWin->nextSib->prevSib = pWin->prevSib;
- if (pWin->prevSib)
- pWin->prevSib->nextSib = pWin->nextSib;
- /* insert at begining of pParent */
- pWin->parent = pParent;
- pPrev = RealChildHead(pParent);
- if (pPrev) {
- pWin->nextSib = pPrev->nextSib;
- if (pPrev->nextSib)
- pPrev->nextSib->prevSib = pWin;
- else
- pParent->lastChild = pWin;
- pPrev->nextSib = pWin;
- pWin->prevSib = pPrev;
- }
- else {
- pWin->nextSib = pParent->firstChild;
- pWin->prevSib = NullWindow;
- if (pParent->firstChild)
- pParent->firstChild->prevSib = pWin;
- else
- pParent->lastChild = pWin;
- pParent->firstChild = pWin;
- }
- pWin->origin.x = x + bw;
- pWin->origin.y = y + bw;
- pWin->drawable.x = x + bw + pParent->drawable.x;
- pWin->drawable.y = y + bw + pParent->drawable.y;
- /* clip to parent */
- SetWinSize(pWin);
- SetBorderSize(pWin);
- if (pScreen->ReparentWindow)
- (*pScreen->ReparentWindow) (pWin, pPriorParent);
- (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y);
- ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
- CheckWindowOptionalNeed(pWin);
- if (WasMapped)
- MapWindow(pWin, client);
- RecalculateDeliverableEvents(pWin);
- return (Success);
- }
- static void
- RealizeTree(WindowPtr pWin)
- {
- WindowPtr pChild;
- RealizeWindowProcPtr Realize;
- Realize = pWin->drawable.pScreen->RealizeWindow;
- pChild = pWin;
- while (1) {
- if (pChild->mapped) {
- pChild->realized = TRUE;
- pChild->viewable = (pChild->drawable.class == InputOutput);
- (*Realize) (pChild);
- if (pChild->firstChild) {
- pChild = pChild->firstChild;
- continue;
- }
- }
- while (!pChild->nextSib && (pChild != pWin))
- pChild = pChild->parent;
- if (pChild == pWin)
- return;
- pChild = pChild->nextSib;
- }
- }
- /*****
- * MapWindow
- * If some other client has selected SubStructureReDirect on the parent
- * and override-redirect is xFalse, then a MapRequest event is generated,
- * but the window remains unmapped. Otherwise, the window is mapped and a
- * MapNotify event is generated.
- *****/
- _X_EXPORT int
- MapWindow(register WindowPtr pWin, ClientPtr client)
- {
- ScreenPtr pScreen;
- WindowPtr pParent;
- WindowPtr pLayerWin;
- if (pWin->mapped)
- return (Success);
- pScreen = pWin->drawable.pScreen;
- if ((pParent = pWin->parent)) {
- xEvent event;
- Bool anyMarked;
- if ((!pWin->overrideRedirect) && (RedirectSend(pParent)
- )) {
- event.u.u.type = MapRequest;
- event.u.mapRequest.window = pWin->drawable.id;
- event.u.mapRequest.parent = pParent->drawable.id;
- if (MaybeDeliverEventsToClient(pParent, &event, 1,
- SubstructureRedirectMask,
- client) == 1)
- return (Success);
- }
- pWin->mapped = TRUE;
- if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin)) {
- event.u.u.type = MapNotify;
- event.u.mapNotify.window = pWin->drawable.id;
- event.u.mapNotify.override = pWin->overrideRedirect;
- DeliverEvents(pWin, &event, 1, NullWindow);
- }
- if (!pParent->realized)
- return (Success);
- RealizeTree(pWin);
- if (pWin->viewable) {
- anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin,
- &pLayerWin);
- if (anyMarked) {
- (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTMap);
- (*pScreen->HandleExposures) (pLayerWin->parent);
- }
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin,
- VTMap);
- }
- WindowsRestructured();
- }
- else {
- RegionRec temp;
- pWin->mapped = TRUE;
- pWin->realized = TRUE; /* for roots */
- pWin->viewable = pWin->drawable.class == InputOutput;
- /* We SHOULD check for an error value here XXX */
- (*pScreen->RealizeWindow) (pWin);
- if (pScreen->ClipNotify)
- (*pScreen->ClipNotify) (pWin, 0, 0);
- if (pScreen->PostValidateTree)
- (*pScreen->PostValidateTree) (NullWindow, pWin, VTMap);
- REGION_NULL(&temp);
- REGION_COPY(&temp, &pWin->clipList);
- (*pScreen->WindowExposures) (pWin, &temp, NullRegion);
- REGION_UNINIT(&temp);
- }
- return (Success);
- }
- /*****
- * MapSubwindows
- * Performs a MapWindow all unmapped children of the window, in top
- * to bottom stacking order.
- *****/
- void
- MapSubwindows(register WindowPtr pParent, ClientPtr client)
- {
- WindowPtr pWin;
- WindowPtr pFirstMapped = NullWindow;
- ScreenPtr pScreen;
- Mask parentRedirect;
- Mask parentNotify;
- xEvent event;
- Bool anyMarked;
- WindowPtr pLayerWin;
- pScreen = pParent->drawable.pScreen;
- parentRedirect = RedirectSend(pParent);
- parentNotify = SubSend(pParent);
- anyMarked = FALSE;
- for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib) {
- if (!pWin->mapped) {
- if (parentRedirect && !pWin->overrideRedirect) {
- event.u.u.type = MapRequest;
- event.u.mapRequest.window = pWin->drawable.id;
- event.u.mapRequest.parent = pParent->drawable.id;
- if (MaybeDeliverEventsToClient(pParent, &event, 1,
- SubstructureRedirectMask,
- client) == 1)
- continue;
- }
- pWin->mapped = TRUE;
- if (parentNotify || StrSend(pWin)) {
- event.u.u.type = MapNotify;
- event.u.mapNotify.window = pWin->drawable.id;
- event.u.mapNotify.override = pWin->overrideRedirect;
- DeliverEvents(pWin, &event, 1, NullWindow);
- }
- if (!pFirstMapped)
- pFirstMapped = pWin;
- if (pParent->realized) {
- RealizeTree(pWin);
- if (pWin->viewable) {
- anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin,
- (WindowPtr
- *) NULL);
- }
- }
- }
- }
- if (pFirstMapped) {
- pLayerWin = (*pScreen->GetLayerWindow) (pParent);
- if (pLayerWin->parent != pParent) {
- anyMarked |= (*pScreen->MarkOverlappedWindows) (pLayerWin,
- pLayerWin,
- (WindowPtr *) NULL);
- pFirstMapped = pLayerWin;
- }
- if (anyMarked) {
- (*pScreen->ValidateTree) (pLayerWin->parent, pFirstMapped, VTMap);
- (*pScreen->HandleExposures) (pLayerWin->parent);
- }
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstMapped,
- VTMap);
- WindowsRestructured();
- }
- }
- static void
- UnrealizeTree(WindowPtr pWin, Bool fromConfigure)
- {
- WindowPtr pChild;
- UnrealizeWindowProcPtr Unrealize;
- MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
- Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
- MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
- pChild = pWin;
- while (1) {
- if (pChild->realized) {
- pChild->realized = FALSE;
- pChild->visibility = VisibilityNotViewable;
- (*Unrealize) (pChild);
- DeleteWindowFromAnyEvents(pChild, FALSE);
- if (pChild->viewable) {
- pChild->viewable = FALSE;
- (*MarkUnrealizedWindow) (pChild, pWin, fromConfigure);
- pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- }
- if (pChild->firstChild) {
- pChild = pChild->firstChild;
- continue;
- }
- }
- while (!pChild->nextSib && (pChild != pWin))
- pChild = pChild->parent;
- if (pChild == pWin)
- return;
- pChild = pChild->nextSib;
- }
- }
- /*****
- * UnmapWindow
- * If the window is already unmapped, this request has no effect.
- * Otherwise, the window is unmapped and an UnMapNotify event is
- * generated. Cannot unmap a root window.
- *****/
- _X_EXPORT int
- UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
- {
- WindowPtr pParent;
- xEvent event;
- Bool wasRealized = (Bool) pWin->realized;
- Bool wasViewable = (Bool) pWin->viewable;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- WindowPtr pLayerWin = pWin;
- if ((!pWin->mapped) || (!(pParent = pWin->parent)))
- return (Success);
- if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin)) {
- event.u.u.type = UnmapNotify;
- event.u.unmapNotify.window = pWin->drawable.id;
- event.u.unmapNotify.fromConfigure = fromConfigure;
- DeliverEvents(pWin, &event, 1, NullWindow);
- }
- if (wasViewable && !fromConfigure) {
- pWin->valdata = UnmapValData;
- (*pScreen->MarkOverlappedWindows) (pWin, pWin->nextSib, &pLayerWin);
- (*pScreen->MarkWindow) (pLayerWin->parent);
- }
- pWin->mapped = FALSE;
- if (wasRealized)
- UnrealizeTree(pWin, fromConfigure);
- if (wasViewable) {
- if (!fromConfigure) {
- (*pScreen->ValidateTree) (pLayerWin->parent, pWin, VTUnmap);
- (*pScreen->HandleExposures) (pLayerWin->parent);
- }
- if (!fromConfigure && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree) (pLayerWin->parent, pWin, VTUnmap);
- }
- if (wasRealized && !fromConfigure)
- WindowsRestructured();
- return (Success);
- }
- /*****
- * UnmapSubwindows
- * Performs an UnmapWindow request with the specified mode on all mapped
- * children of the window, in bottom to top stacking order.
- *****/
- void
- UnmapSubwindows(register WindowPtr pWin)
- {
- WindowPtr pChild, pHead;
- xEvent event;
- Bool wasRealized = (Bool) pWin->realized;
- Bool wasViewable = (Bool) pWin->viewable;
- Bool anyMarked = FALSE;
- Mask parentNotify;
- WindowPtr pLayerWin = NULL;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- if (!pWin->firstChild)
- return;
- parentNotify = SubSend(pWin);
- pHead = RealChildHead(pWin);
- if (wasViewable)
- pLayerWin = (*pScreen->GetLayerWindow) (pWin);
- for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) {
- if (pChild->mapped) {
- if (parentNotify || StrSend(pChild)) {
- event.u.u.type = UnmapNotify;
- event.u.unmapNotify.window = pChild->drawable.id;
- event.u.unmapNotify.fromConfigure = xFalse;
- DeliverEvents(pChild, &event, 1, NullWindow);
- }
- if (pChild->viewable) {
- pChild->valdata = UnmapValData;
- anyMarked = TRUE;
- }
- pChild->mapped = FALSE;
- if (pChild->realized)
- UnrealizeTree(pChild, FALSE);
- if (wasViewable) {
- }
- }
- }
- if (wasViewable) {
- if (anyMarked) {
- if (pLayerWin->parent == pWin)
- (*pScreen->MarkWindow) (pWin);
- else {
- WindowPtr ptmp;
- (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin,
- (WindowPtr *) NULL);
- (*pScreen->MarkWindow) (pLayerWin->parent);
- /* Windows between pWin and pLayerWin may not have been marked */
- ptmp = pWin;
- while (ptmp != pLayerWin->parent) {
- (*pScreen->MarkWindow) (ptmp);
- ptmp = ptmp->parent;
- }
- pHead = pWin->firstChild;
- }
- (*pScreen->ValidateTree) (pLayerWin->parent, pHead, VTUnmap);
- (*pScreen->HandleExposures) (pLayerWin->parent);
- }
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree) (pLayerWin->parent, pHead, VTUnmap);
- }
- if (wasRealized)
- WindowsRestructured();
- }
- void
- HandleSaveSet(register ClientPtr client)
- {
- WindowPtr pParent, pWin;
- int j;
- for (j = 0; j < client->numSaved; j++) {
- pWin = SaveSetWindow(client->saveSet[j]);
- if (SaveSetToRoot(client->saveSet[j]))
- pParent = WindowTable[pWin->drawable.pScreen->myNum];
- else
- {
- pParent = pWin->parent;
- while (pParent && (wClient(pParent) == client))
- pParent = pParent->parent;
- }
- if (pParent) {
- if (pParent != pWin->parent) {
- ReparentWindow(pWin, pParent,
- pWin->drawable.x - wBorderWidth(pWin) -
- pParent->drawable.x,
- pWin->drawable.y - wBorderWidth(pWin) -
- pParent->drawable.y, client);
- if (!pWin->realized && pWin->mapped)
- pWin->mapped = FALSE;
- }
- if (SaveSetRemap(client->saveSet[j]))
- MapWindow(pWin, client);
- }
- }
- free(client->saveSet);
- client->numSaved = 0;
- client->saveSet = (SaveSetElt *) NULL;
- }
- /**
- *
- * \param x,y in root
- * \param box "return" value
- */
- Bool
- VisibleBoundingBoxFromPoint(register WindowPtr pWin, int x, int y, BoxPtr box)
- {
- if (!pWin->realized)
- return (FALSE);
- if (POINT_IN_REGION(&pWin->clipList, x, y, box))
- return (TRUE);
- return (FALSE);
- }
- /**
- *
- * \param x,y in root
- */
- Bool
- PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
- {
- BoxRec box;
- if (!pWin->realized)
- return (FALSE);
- if (POINT_IN_REGION(&pWin->borderClip, x, y, &box)
- && (!wInputShape(pWin) ||
- POINT_IN_REGION(
- wInputShape(pWin),
- x - pWin->drawable.x, y - pWin->drawable.y, &box)))
- return (TRUE);
- return (FALSE);
- }
- _X_EXPORT RegionPtr
- NotClippedByChildren(register WindowPtr pWin)
- {
- RegionPtr pReg;
- pReg = REGION_CREATE(NullBox, 1);
- if (pWin->parent ||
- screenIsSaved != SCREEN_SAVER_ON ||
- !HasSaverWindow(pWin->drawable.pScreen->myNum)) {
- REGION_INTERSECT(pReg, &pWin->borderClip, &pWin->winSize);
- }
- return (pReg);
- }
- _X_EXPORT void
- SendVisibilityNotify(WindowPtr pWin)
- {
- xEvent event;
- #ifndef NO_XINERAMA_PORT
- unsigned int visibility = pWin->visibility;
- #endif
- event.u.u.type = VisibilityNotify;
- event.u.visibility.window = pWin->drawable.id;
- event.u.visibility.state = visibility;
- DeliverEvents(pWin, &event, 1, NullWindow);
- }
- static WindowPtr windowDisableMapUnmapEvents;
- void
- DisableMapUnmapEvents(WindowPtr pWin)
- {
- assert(windowDisableMapUnmapEvents == NULL);
- windowDisableMapUnmapEvents = pWin;
- }
- void
- EnableMapUnmapEvents(WindowPtr pWin)
- {
- assert(windowDisableMapUnmapEvents != NULL);
- windowDisableMapUnmapEvents = NULL;
- }
- Bool
- MapUnmapEventsEnabled(WindowPtr pWin)
- {
- return pWin != windowDisableMapUnmapEvents;
- }
- #define RANDOM_WIDTH 32
- #ifndef NOLOGOHACK
- static void DrawLogo(WindowPtr pWin);
- #endif
- _X_EXPORT void
- SaveScreens(int on, int mode)
- {
- int i;
- int what;
- int type;
- if (on == SCREEN_SAVER_FORCER) {
- UpdateCurrentTimeIf();
- lastDeviceEventTime = currentTime;
- if (mode == ScreenSaverReset)
- what = SCREEN_SAVER_OFF;
- else
- what = SCREEN_SAVER_ON;
- type = what;
- }
- else {
- what = on;
- type = what;
- if (what == screenIsSaved)
- type = SCREEN_SAVER_CYCLE;
- }
- for (i = 0; i < screenInfo.numScreens; i++) {
- if (on == SCREEN_SAVER_FORCER)
- (*screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
- if (savedScreenInfo[i].ExternalScreenSaver) {
- if ((*savedScreenInfo[i].ExternalScreenSaver)
- (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
- continue;
- }
- if (type == screenIsSaved)
- continue;
- switch (type) {
- case SCREEN_SAVER_OFF:
- if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED) {
- (*screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
- what);
- }
- else if (HasSaverWindow(i)) {
- savedScreenInfo[i].pWindow = NullWindow;
- FreeResource(savedScreenInfo[i].wid, RT_NONE);
- }
- break;
- case SCREEN_SAVER_CYCLE:
- if (savedScreenInfo[i].blanked == SCREEN_IS_TILED) {
- WindowPtr pWin = savedScreenInfo[i].pWindow;
- /* make it look like screen saver is off, so that
- * NotClippedByChildren will compute a clip list
- * for the root window, so miPaintWindow works
- */
- screenIsSaved = SCREEN_SAVER_OFF;
- #ifndef NOLOGOHACK
- if (logoScreenSaver)
- (*pWin->drawable.pScreen->ClearToBackground) (pWin, 0, 0, 0,
- 0, FALSE);
- #endif
- (*pWin->drawable.pScreen->MoveWindow) (pWin,
- (short) (-
- (rand() %
- RANDOM_WIDTH)),
- (short) (-
- (rand() %
- RANDOM_WIDTH)),
- pWin->nextSib, VTMove);
- #ifndef NOLOGOHACK
- if (logoScreenSaver)
- DrawLogo(pWin);
- #endif
- screenIsSaved = SCREEN_SAVER_ON;
- }
- /*
- * Call the DDX saver in case it wants to do something
- * at cycle time
- */
- else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED) {
- (*screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
- type);
- }
- break;
- case SCREEN_SAVER_ON:
- if (ScreenSaverBlanking != DontPreferBlanking) {
- if ((*screenInfo.screens[i]->SaveScreen)
- (screenInfo.screens[i], what)) {
- savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
- continue;
- }
- if ((ScreenSaverAllowExposures != DontAllowExposures) &&
- TileScreenSaver(i, SCREEN_IS_BLACK)) {
- savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
- continue;
- }
- }
- if ((ScreenSaverAllowExposures != DontAllowExposures) &&
- TileScreenSaver(i, SCREEN_IS_TILED)) {
- savedScreenInfo[i].blanked = SCREEN_IS_TILED;
- }
- else
- savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
- break;
- }
- }
- screenIsSaved = what;
- if (mode == ScreenSaverReset)
- SetScreenSaverTimer();
- }
- static Bool
- TileScreenSaver(int i, int kind)
- {
- int j;
- int result;
- XID attributes[3];
- Mask mask;
- WindowPtr pWin;
- CursorMetricRec cm;
- unsigned char *srcbits, *mskbits;
- CursorPtr cursor;
- XID cursorID = 0;
- int attri;
- mask = 0;
- attri = 0;
- switch (kind) {
- case SCREEN_IS_TILED:
- switch (WindowTable[i]->backgroundState) {
- case BackgroundPixel:
- attributes[attri++] = WindowTable[i]->background.pixel;
- mask |= CWBackPixel;
- break;
- case BackgroundPixmap:
- attributes[attri++] = None;
- mask |= CWBackPixmap;
- break;
- default:
- break;
- }
- break;
- case SCREEN_IS_BLACK:
- attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
- mask |= CWBackPixel;
- break;
- }
- mask |= CWOverrideRedirect;
- attributes[attri++] = xTrue;
- /*
- * create a blank cursor
- */
- cm.width = 16;
- cm.height = 16;
- cm.xhot = 8;
- cm.yhot = 8;
- srcbits = malloc(BitmapBytePad(32) * 16);
- mskbits = malloc(BitmapBytePad(32) * 16);
- if (!srcbits || !mskbits) {
- free(srcbits);
- free(mskbits);
- cursor = 0;
- }
- else {
- for (j = 0; j < BitmapBytePad(32) * 16; j++)
- srcbits[j] = mskbits[j] = 0x0;
- cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
- if (cursor) {
- cursorID = FakeClientID(0);
- if (AddResource(cursorID, RT_CURSOR, (pointer) cursor)) {
- attributes[attri] = cursorID;
- mask |= CWCursor;
- }
- else
- cursor = 0;
- }
- else {
- free(srcbits);
- free(mskbits);
- }
- }
- pWin = savedScreenInfo[i].pWindow =
- CreateWindow(savedScreenInfo[i].wid,
- WindowTable[i],
- -RANDOM_WIDTH, -RANDOM_WIDTH,
- (unsigned short) screenInfo.screens[i]->width +
- RANDOM_WIDTH,
- (unsigned short) screenInfo.screens[i]->height +
- RANDOM_WIDTH, 0, InputOutput, mask, attributes, 0,
- serverClient, wVisual(WindowTable[i]), &result);
- if (cursor)
- FreeResource(cursorID, RT_NONE);
- if (!pWin)
- return FALSE;
- if (!AddResource(pWin->drawable.id, RT_WINDOW,
- (pointer) savedScreenInfo[i].pWindow))
- return FALSE;
- if (mask & CWBackPixmap) {
- MakeRootTile(pWin);
- (*pWin->drawable.pScreen->ChangeWindowAttributes) (pWin, CWBackPixmap);
- }
- MapWindow(pWin, serverClient);
- #ifndef NOLOGOHACK
- if (kind == SCREEN_IS_TILED && logoScreenSaver)
- DrawLogo(pWin);
- #endif
- return TRUE;
- }
- /*
- * FindWindowWithOptional
- *
- * search ancestors of the given window for an entry containing
- * a WindowOpt structure. Assumptions: some parent will
- * contain the structure.
- */
- _X_EXPORT WindowPtr
- FindWindowWithOptional(register WindowPtr w)
- {
- do
- w = w->parent;
- while (!w->optional);
- return w;
- }
- /*
- * CheckWindowOptionalNeed
- *
- * check each optional entry in the given window to see if
- * the value is satisfied by the default rules. If so,
- * release the optional record
- */
- _X_EXPORT void
- CheckWindowOptionalNeed(register WindowPtr w)
- {
- WindowOptPtr optional;
- WindowOptPtr parentOptional;
- if (!w->parent)
- return;
- optional = w->optional;
- if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
- return;
- if (optional->otherEventMasks != 0)
- return;
- if (optional->otherClients != NULL)
- return;
- if (optional->passiveGrabs != NULL)
- return;
- if (optional->userProps != NULL)
- return;
- if (optional->backingBitPlanes != ~0L)
- return;
- if (optional->backingPixel != 0)
- return;
- if (optional->boundingShape != NULL)
- return;
- if (optional->clipShape != NULL)
- return;
- if (optional->inputShape != NULL)
- return;
- parentOptional = FindWindowWithOptional(w)->optional;
- if (optional->visual != parentOptional->visual)
- return;
- if (optional->cursor != None &&
- (optional->cursor != parentOptional->cursor || w->parent->cursorIsNone))
- return;
- if (optional->colormap != parentOptional->colormap)
- return;
- DisposeWindowOptional(w);
- }
- /*
- * MakeWindowOptional
- *
- * create an optional record and initialize it with the default
- * values.
- */
- _X_EXPORT Bool
- MakeWindowOptional(register WindowPtr pWin)
- {
- WindowOptPtr optional;
- WindowOptPtr parentOptional;
- if (pWin->optional)
- return TRUE;
- optional = malloc(sizeof(WindowOptRec));
- if (!optional)
- return FALSE;
- optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
- optional->otherEventMasks = 0;
- optional->otherClients = NULL;
- optional->passiveGrabs = NULL;
- optional->userProps = NULL;
- optional->backingBitPlanes = ~0L;
- optional->backingPixel = 0;
- optional->boundingShape = NULL;
- optional->clipShape = NULL;
- optional->inputShape = NULL;
- parentOptional = FindWindowWithOptional(pWin)->optional;
- optional->visual = parentOptional->visual;
- if (!pWin->cursorIsNone) {
- optional->cursor = parentOptional->cursor;
- optional->cursor->refcnt++;
- }
- else {
- optional->cursor = None;
- }
- optional->colormap = parentOptional->colormap;
- pWin->optional = optional;
- return TRUE;
- }
- void
- DisposeWindowOptional(register WindowPtr pWin)
- {
- if (!pWin->optional)
- return;
- /*
- * everything is peachy. Delete the optional record
- * and clean up
- */
- /*
- * TOG changed this code to:
- *
- * if (pWin->cursorIsNone == FALSE)
- * FreeCursor (pWin->optional->cursor, (Cursor)0);
- * pWin->cursorIsNone = TRUE;
- *
- * This is blatently wrong; windows without optionals can have
- * two different cursor values, either None or sharing their
- * parents cursor. This difference is controlled by the
- * cursorIsNone value; when TRUE, the window has no cursor,
- * when false, it shares its cursor with its parent; TOG
- * made it impossible for a window to have a cursor without
- * an optional record.
- */
- if (pWin->optional->cursor) {
- FreeCursor(pWin->optional->cursor, (Cursor) 0);
- pWin->cursorIsNone = FALSE;
- }
- else
- pWin->cursorIsNone = TRUE;
- free(pWin->optional);
- pWin->optional = NULL;
- }
- #ifndef NOLOGOHACK
- static void
- DrawLogo(WindowPtr pWin)
- {
- DrawablePtr pDraw;
- ScreenPtr pScreen;
- int x, y;
- unsigned int width, height, size;
- GC *pGC;
- int thin, gap, d31;
- DDXPointRec poly[4];
- ChangeGCVal fore[2], back[2];
- xrgb rgb[2];
- BITS32 fmask, bmask;
- ColormapPtr cmap;
- pDraw = (DrawablePtr) pWin;
- pScreen = pDraw->pScreen;
- x = -pWin->origin.x;
- y = -pWin->origin.y;
- width = pScreen->width;
- height = pScreen->height;
- pGC = GetScratchGC(pScreen->rootDepth, pScreen);
- if (!pGC)
- return;
- if ((rand() % 100) <= 17) /* make the probability for white fairly low */
- fore[0].val = pScreen->whitePixel;
- else
- fore[0].val = pScreen->blackPixel;
- if ((pWin->backgroundState == BackgroundPixel) &&
- (cmap = (ColormapPtr) LookupIDByType(wColormap(pWin), RT_COLORMAP))) {
- Pixel querypixels[2];
- querypixels[0] = fore[0].val;
- querypixels[1] = pWin->background.pixel;
- QueryColors(cmap, 2, querypixels, rgb);
- if ((rgb[0].red == rgb[1].red) &&
- (rgb[0].green == rgb[1].green) && (rgb[0].blue == rgb[1].blue)) {
- if (fore[0].val == pScreen->blackPixel)
- fore[0].val = pScreen->whitePixel;
- else
- fore[0].val = pScreen->blackPixel;
- }
- }
- fore[1].val = FillSolid;
- fmask = GCForeground | GCFillStyle;
- if (pWin->backgroundState == BackgroundPixel) {
- back[0].val = pWin->background.pixel;
- back[1].val = FillSolid;
- bmask = GCForeground | GCFillStyle;
- }
- else {
- back[0].val = 0;
- back[1].val = 0;
- dixChangeGC(NullClient, pGC, GCTileStipXOrigin | GCTileStipYOrigin,
- NULL, back);
- back[0].val = FillTiled;
- back[1].ptr = pWin->background.pixmap;
- bmask = GCFillStyle | GCTile;
- }
- /* should be the same as the reference function XmuDrawLogo() */
- size = width;
- if (height < width)
- size = height;
- size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
- size &= ~1;
- x += rand() % (width - size);
- y += rand() % (height - size);
- /*
- * Draw what will be the thin strokes.
- *
- * -----
- * / /
- * / /
- * / /
- * / /
- * /____/
- * d
- *
- * Point d is 9/44 (~1/5) of the way across.
- */
- thin = (size / 11);
- if (thin < 1)
- thin = 1;
- gap = (thin + 3) / 4;
- d31 = thin + thin + gap;
- poly[0].x = x + size;
- poly[0].y = y;
- poly[1].x = x + size - d31;
- poly[1].y = y;
- poly[2].x = x + 0;
- poly[2].y = y + size;
- poly[3].x = x + d31;
- poly[3].y = y + size;
- dixChangeGC(NullClient, pGC, fmask, NULL, fore);
- ValidateGC(pDraw, pGC);
- (*pGC->ops->FillPolygon) (pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
- /*
- * Erase area not needed for lower thin stroke.
- *
- * ------
- * / /
- * / __ /
- * / / /
- * / / /
- * /__/__/
- */
- poly[0].x = x + d31 / 2;
- poly[0].y = y + size;
- poly[1].x = x + size / 2;
- poly[1].y = y + size / 2;
- poly[2].x = x + (size / 2) + (d31 - (d31 / 2));
- poly[2].y = y + size / 2;
- poly[3].x = x + d31;
- poly[3].y = y + size;
- dixChangeGC(NullClient, pGC, bmask, NULL, back);
- ValidateGC(pDraw, pGC);
- (*pGC->ops->FillPolygon) (pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
- /*
- * Erase area not needed for upper thin stroke.
- *
- * ------
- * / / /
- * /--/ /
- * / /
- * / /
- * /_____/
- */
- poly[0].x = x + size - d31 / 2;
- poly[0].y = y;
- poly[1].x = x + size / 2;
- poly[1].y = y + size / 2;
- poly[2].x = x + (size / 2) - (d31 - (d31 / 2));
- poly[2].y = y + size / 2;
- poly[3].x = x + size - d31;
- poly[3].y = y;
- ValidateGC(pDraw, pGC);
- (*pGC->ops->FillPolygon) (pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
- /*
- * Draw thick stroke.
- * Point b is 1/4 of the way across.
- *
- * b
- * -----
- * \ \
- * \ \
- * \ \
- * \ \
- * \____\
- */
- poly[0].x = x;
- poly[0].y = y;
- poly[1].x = x + size / 4;
- poly[1].y = y;
- poly[2].x = x + size;
- poly[2].y = y + size;
- poly[3].x = x + size - size / 4;
- poly[3].y = y + size;
- dixChangeGC(NullClient, pGC, fmask, NULL, fore);
- ValidateGC(pDraw, pGC);
- (*pGC->ops->FillPolygon) (pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
- /*
- * Erase to create gap.
- *
- * /
- * /
- * /
- * /
- * /
- */
- poly[0].x = x + size - thin;
- poly[0].y = y;
- poly[1].x = x + size - (thin + gap);
- poly[1].y = y;
- poly[2].x = x + thin;
- poly[2].y = y + size;
- poly[3].x = x + thin + gap;
- poly[3].y = y + size;
- dixChangeGC(NullClient, pGC, bmask, NULL, back);
- ValidateGC(pDraw, pGC);
- (*pGC->ops->FillPolygon) (pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
- FreeScratchGC(pGC);
- }
- #endif
|