window.c 99 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363
  1. /*
  2. Copyright (c) 2006, Red Hat, Inc.
  3. Permission to use, copy, modify, distribute, and sell this software and its
  4. documentation for any purpose is hereby granted without fee, provided that
  5. the above copyright notice appear in all copies and that both that
  6. copyright notice and this permission notice appear in supporting
  7. documentation.
  8. The above copyright notice and this permission notice shall be included in
  9. all copies or substantial portions of the Software.
  10. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  11. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  12. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  13. RED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  14. IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  15. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16. Except as contained in this notice, the name of Red Hat shall not be
  17. used in advertising or otherwise to promote the sale, use or other dealings
  18. in this Software without prior written authorization from Red Hat.
  19. Copyright 1987, 1998 The Open Group
  20. Permission to use, copy, modify, distribute, and sell this software and its
  21. documentation for any purpose is hereby granted without fee, provided that
  22. the above copyright notice appear in all copies and that both that
  23. copyright notice and this permission notice appear in supporting
  24. documentation.
  25. The above copyright notice and this permission notice shall be included
  26. in all copies or substantial portions of the Software.
  27. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  28. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  29. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  30. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
  31. OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  32. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  33. OTHER DEALINGS IN THE SOFTWARE.
  34. Except as contained in this notice, the name of The Open Group shall
  35. not be used in advertising or otherwise to promote the sale, use or
  36. other dealings in this Software without prior written authorization
  37. from The Open Group.
  38. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  39. All Rights Reserved
  40. Permission to use, copy, modify, and distribute this software and its
  41. documentation for any purpose and without fee is hereby granted,
  42. provided that the above copyright notice appear in all copies and that
  43. both that copyright notice and this permission notice appear in
  44. supporting documentation, and that the name of Digital not be
  45. used in advertising or publicity pertaining to distribution of the
  46. software without specific, written prior permission.
  47. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  48. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  49. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  50. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  51. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  52. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  53. SOFTWARE.
  54. */
  55. #ifdef HAVE_DIX_CONFIG_H
  56. #include <dix-config.h>
  57. #endif
  58. #include "misc.h"
  59. #include "scrnintstr.h"
  60. #include "os.h"
  61. #include "regionstr.h"
  62. #include "validate.h"
  63. #include "windowstr.h"
  64. #include "input.h"
  65. #include "resource.h"
  66. #include "colormapst.h"
  67. #include "cursorstr.h"
  68. #include "dixstruct.h"
  69. #include "gcstruct.h"
  70. #include "servermd.h"
  71. #include "dixevents.h"
  72. #include "globals.h"
  73. /******
  74. * Window stuff for server
  75. *
  76. * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
  77. * GetWindowAttributes, DeleteWindow, DestroySubWindows,
  78. * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
  79. * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
  80. *
  81. ******/
  82. static const unsigned char _back_lsb[4] = { 0x88, 0x22, 0x44, 0x11 };
  83. static const unsigned char _back_msb[4] = { 0x11, 0x44, 0x22, 0x88 };
  84. _X_EXPORT int screenIsSaved = SCREEN_SAVER_OFF;
  85. _X_EXPORT ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
  86. static Bool TileScreenSaver(int i, int kind);
  87. #define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
  88. CWDontPropagate | CWOverrideRedirect | CWCursor )
  89. #define BOXES_OVERLAP(b1, b2) \
  90. (!( ((b1)->x2 <= (b2)->x1) || \
  91. ( ((b1)->x1 >= (b2)->x2)) || \
  92. ( ((b1)->y2 <= (b2)->y1)) || \
  93. ( ((b1)->y1 >= (b2)->y2)) ) )
  94. #define RedirectSend(pWin) \
  95. ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
  96. #define SubSend(pWin) \
  97. ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
  98. #define StrSend(pWin) \
  99. ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
  100. #define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
  101. #ifdef DEBUG
  102. /******
  103. * PrintWindowTree
  104. * For debugging only
  105. ******/
  106. int
  107. PrintChildren(WindowPtr p1, int indent)
  108. {
  109. WindowPtr p2;
  110. int i;
  111. while (p1) {
  112. p2 = p1->firstChild;
  113. for (i = 0; i < indent; i++)
  114. ErrorF(" ");
  115. ErrorF("%x\n", p1->drawable.id);
  116. miPrintRegion(&p1->clipList);
  117. PrintChildren(p2, indent + 4);
  118. p1 = p1->nextSib;
  119. }
  120. }
  121. PrintWindowTree()
  122. {
  123. int i;
  124. WindowPtr pWin, p1;
  125. for (i = 0; i < screenInfo.numScreens; i++) {
  126. ErrorF("WINDOW %d\n", i);
  127. pWin = WindowTable[i];
  128. miPrintRegion(&pWin->clipList);
  129. p1 = pWin->firstChild;
  130. PrintChildren(p1, 4);
  131. }
  132. }
  133. #endif
  134. _X_EXPORT int
  135. TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, pointer data)
  136. {
  137. int result;
  138. WindowPtr pChild;
  139. if (!(pChild = pWin))
  140. return (WT_NOMATCH);
  141. while (1) {
  142. result = (*func) (pChild, data);
  143. if (result == WT_STOPWALKING)
  144. return (WT_STOPWALKING);
  145. if ((result == WT_WALKCHILDREN) && pChild->firstChild) {
  146. pChild = pChild->firstChild;
  147. continue;
  148. }
  149. while (!pChild->nextSib && (pChild != pWin))
  150. pChild = pChild->parent;
  151. if (pChild == pWin)
  152. break;
  153. pChild = pChild->nextSib;
  154. }
  155. return (WT_NOMATCH);
  156. }
  157. /*****
  158. * WalkTree
  159. * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
  160. * each window. If FUNC returns WT_WALKCHILDREN, traverse the children,
  161. * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING
  162. * exit WalkTree. Does depth-first traverse.
  163. *****/
  164. _X_EXPORT int
  165. WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
  166. {
  167. return (TraverseTree(WindowTable[pScreen->myNum], func, data));
  168. }
  169. /* hack for forcing backing store on all windows */
  170. static const int defaultBackingStore = NotUseful;
  171. static void
  172. SetWindowToDefaults(register WindowPtr pWin)
  173. {
  174. pWin->prevSib = NullWindow;
  175. pWin->firstChild = NullWindow;
  176. pWin->lastChild = NullWindow;
  177. pWin->valdata = (ValidatePtr) NULL;
  178. pWin->optional = (WindowOptPtr) NULL;
  179. pWin->cursorIsNone = TRUE;
  180. pWin->backingStore = NotUseful;
  181. pWin->DIXsaveUnder = FALSE;
  182. pWin->backStorage = (pointer) NULL;
  183. pWin->mapped = FALSE; /* off */
  184. pWin->realized = FALSE; /* off */
  185. pWin->viewable = FALSE;
  186. pWin->visibility = VisibilityNotViewable;
  187. pWin->overrideRedirect = FALSE;
  188. pWin->saveUnder = FALSE;
  189. pWin->bitGravity = ForgetGravity;
  190. pWin->winGravity = NorthWestGravity;
  191. pWin->eventMask = 0;
  192. pWin->deliverableEvents = 0;
  193. pWin->dontPropagate = 0;
  194. pWin->forcedBS = FALSE;
  195. #ifdef NEED_DBE_BUF_BITS
  196. pWin->srcBuffer = DBE_FRONT_BUFFER;
  197. pWin->dstBuffer = DBE_FRONT_BUFFER;
  198. #endif
  199. }
  200. static void
  201. MakeRootTile(WindowPtr pWin)
  202. {
  203. ScreenPtr pScreen = pWin->drawable.pScreen;
  204. GCPtr pGC;
  205. unsigned char back[128];
  206. int len = BitmapBytePad(sizeof(long));
  207. const unsigned char *from;
  208. unsigned char *to;
  209. int i, j;
  210. pWin->background.pixmap = (*pScreen->CreatePixmap) (pScreen, 4, 4,
  211. pScreen->rootDepth);
  212. pWin->backgroundState = BackgroundPixmap;
  213. pGC = GetScratchGC(pScreen->rootDepth, pScreen);
  214. if (!pWin->background.pixmap || !pGC)
  215. FatalError("could not create root tile");
  216. {
  217. CARD32 attributes[2];
  218. attributes[0] = pScreen->whitePixel;
  219. attributes[1] = pScreen->blackPixel;
  220. (void) ChangeGC(pGC, GCForeground | GCBackground, attributes);
  221. }
  222. ValidateGC((DrawablePtr) pWin->background.pixmap, pGC);
  223. from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
  224. to = back;
  225. for (i = 4; i > 0; i--, from++)
  226. for (j = len; j > 0; j--)
  227. *to++ = *from;
  228. (*pGC->ops->PutImage) ((DrawablePtr) pWin->background.pixmap, pGC, 1,
  229. 0, 0, len, 4, 0, XYBitmap, (char *) back);
  230. FreeScratchGC(pGC);
  231. }
  232. WindowPtr
  233. AllocateWindow(ScreenPtr pScreen)
  234. {
  235. WindowPtr pWin;
  236. char *ptr;
  237. DevUnion *ppriv;
  238. unsigned *sizes;
  239. unsigned size;
  240. int i;
  241. pWin = malloc(pScreen->totalWindowSize);
  242. if (pWin) {
  243. ppriv = (DevUnion *) (pWin + 1);
  244. pWin->devPrivates = ppriv;
  245. sizes = pScreen->WindowPrivateSizes;
  246. ptr = (char *) (ppriv + pScreen->WindowPrivateLen);
  247. for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++) {
  248. if ((size = *sizes)) {
  249. ppriv->ptr = (pointer) ptr;
  250. ptr += size;
  251. }
  252. else
  253. ppriv->ptr = (pointer) NULL;
  254. }
  255. #if _XSERVER64
  256. pWin->drawable.pad0 = 0;
  257. pWin->drawable.pad1 = 0;
  258. #endif
  259. }
  260. return pWin;
  261. }
  262. /*****
  263. * CreateRootWindow
  264. * Makes a window at initialization time for specified screen
  265. *****/
  266. Bool
  267. CreateRootWindow(ScreenPtr pScreen)
  268. {
  269. WindowPtr pWin;
  270. BoxRec box;
  271. PixmapFormatRec *format;
  272. pWin = AllocateWindow(pScreen);
  273. if (!pWin)
  274. return FALSE;
  275. savedScreenInfo[pScreen->myNum].pWindow = NULL;
  276. savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
  277. savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
  278. screenIsSaved = SCREEN_SAVER_OFF;
  279. WindowTable[pScreen->myNum] = pWin;
  280. pWin->drawable.pScreen = pScreen;
  281. pWin->drawable.type = DRAWABLE_WINDOW;
  282. pWin->drawable.depth = pScreen->rootDepth;
  283. for (format = screenInfo.formats;
  284. format->depth != pScreen->rootDepth; format++);
  285. pWin->drawable.bitsPerPixel = format->bitsPerPixel;
  286. pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  287. pWin->parent = NullWindow;
  288. SetWindowToDefaults(pWin);
  289. pWin->optional = malloc(sizeof(WindowOptRec));
  290. if (!pWin->optional)
  291. return FALSE;
  292. pWin->optional->dontPropagateMask = 0;
  293. pWin->optional->otherEventMasks = 0;
  294. pWin->optional->otherClients = NULL;
  295. pWin->optional->passiveGrabs = NULL;
  296. pWin->optional->userProps = NULL;
  297. pWin->optional->backingBitPlanes = ~0L;
  298. pWin->optional->backingPixel = 0;
  299. pWin->optional->boundingShape = NULL;
  300. pWin->optional->clipShape = NULL;
  301. pWin->optional->inputShape = NULL;
  302. pWin->optional->colormap = pScreen->defColormap;
  303. pWin->optional->visual = pScreen->rootVisual;
  304. pWin->nextSib = NullWindow;
  305. pWin->drawable.id = FakeClientID(0);
  306. pWin->origin.x = pWin->origin.y = 0;
  307. pWin->drawable.height = pScreen->height;
  308. pWin->drawable.width = pScreen->width;
  309. pWin->drawable.x = pWin->drawable.y = 0;
  310. box.x1 = 0;
  311. box.y1 = 0;
  312. box.x2 = pScreen->width;
  313. box.y2 = pScreen->height;
  314. BoxRec *boxptr = &box;
  315. REGION_INIT(&pWin->clipList, boxptr, 1);
  316. REGION_INIT(&pWin->winSize, boxptr, 1);
  317. REGION_INIT(&pWin->borderSize, boxptr, 1);
  318. REGION_INIT(&pWin->borderClip, boxptr, 1);
  319. pWin->drawable.class = InputOutput;
  320. pWin->optional->visual = pScreen->rootVisual;
  321. pWin->backgroundState = BackgroundPixel;
  322. pWin->background.pixel = pScreen->whitePixel;
  323. pWin->borderIsPixel = TRUE;
  324. pWin->border.pixel = pScreen->blackPixel;
  325. pWin->borderWidth = 0;
  326. if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer) pWin))
  327. return FALSE;
  328. pScreen->saveUnderSupport = NotUseful;
  329. return TRUE;
  330. }
  331. void
  332. InitRootWindow(WindowPtr pWin)
  333. {
  334. ScreenPtr pScreen = pWin->drawable.pScreen;
  335. int backFlag = CWBorderPixel | CWCursor | CWBackingStore;
  336. if (!(*pScreen->CreateWindow) (pWin))
  337. return; /* XXX */
  338. (*pScreen->PositionWindow) (pWin, 0, 0);
  339. pWin->cursorIsNone = FALSE;
  340. pWin->optional->cursor = rootCursor;
  341. rootCursor->refcnt++;
  342. if (!blackRoot && !whiteRoot) {
  343. MakeRootTile(pWin);
  344. backFlag |= CWBackPixmap;
  345. }
  346. else {
  347. if (blackRoot)
  348. pWin->background.pixel = pScreen->blackPixel;
  349. else
  350. pWin->background.pixel = pScreen->whitePixel;
  351. backFlag |= CWBackPixel;
  352. }
  353. pWin->backingStore = defaultBackingStore;
  354. pWin->forcedBS = (defaultBackingStore != NotUseful);
  355. /* We SHOULD check for an error value here XXX */
  356. (*pScreen->ChangeWindowAttributes) (pWin, backFlag);
  357. MapWindow(pWin, serverClient);
  358. }
  359. /* Set the region to the intersection of the rectangle and the
  360. * window's winSize. The window is typically the parent of the
  361. * window from which the region came.
  362. */
  363. void
  364. ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
  365. register int x, register int y,
  366. register int w, register int h)
  367. {
  368. BoxRec box;
  369. box = *(REGION_EXTENTS(&pWin->winSize));
  370. /* we do these calculations to avoid overflows */
  371. if (x > box.x1)
  372. box.x1 = x;
  373. if (y > box.y1)
  374. box.y1 = y;
  375. x += w;
  376. if (x < box.x2)
  377. box.x2 = x;
  378. y += h;
  379. if (y < box.y2)
  380. box.y2 = y;
  381. if (box.x1 > box.x2)
  382. box.x2 = box.x1;
  383. if (box.y1 > box.y2)
  384. box.y2 = box.y1;
  385. REGION_RESET(Rgn, &box);
  386. REGION_INTERSECT(Rgn, Rgn, &pWin->winSize);
  387. }
  388. static RealChildHeadProc realChildHeadProc = NULL;
  389. void
  390. RegisterRealChildHeadProc(RealChildHeadProc proc)
  391. {
  392. realChildHeadProc = proc;
  393. }
  394. WindowPtr
  395. RealChildHead(register WindowPtr pWin)
  396. {
  397. if (realChildHeadProc) {
  398. return realChildHeadProc(pWin);
  399. }
  400. if (!pWin->parent &&
  401. (screenIsSaved == SCREEN_SAVER_ON) &&
  402. (HasSaverWindow(pWin->drawable.pScreen->myNum)))
  403. return (pWin->firstChild);
  404. else
  405. return (NullWindow);
  406. }
  407. /*****
  408. * CreateWindow
  409. * Makes a window in response to client request
  410. *****/
  411. _X_EXPORT WindowPtr
  412. CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
  413. unsigned h, unsigned bw, unsigned class, register Mask vmask,
  414. XID *vlist, int depth, ClientPtr client, VisualID visual,
  415. int *error)
  416. {
  417. WindowPtr pWin;
  418. WindowPtr pHead;
  419. ScreenPtr pScreen;
  420. xEvent event;
  421. int idepth, ivisual;
  422. Bool fOK;
  423. DepthPtr pDepth;
  424. PixmapFormatRec *format;
  425. WindowOptPtr ancwopt;
  426. if (class == CopyFromParent)
  427. class = pParent->drawable.class;
  428. if ((class != InputOutput) && (class != InputOnly)) {
  429. *error = BadValue;
  430. client->errorValue = class;
  431. return NullWindow;
  432. }
  433. if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) {
  434. *error = BadMatch;
  435. return NullWindow;
  436. }
  437. if ((class == InputOnly) && ((bw != 0) || (depth != 0))) {
  438. *error = BadMatch;
  439. return NullWindow;
  440. }
  441. pScreen = pParent->drawable.pScreen;
  442. if ((class == InputOutput) && (depth == 0))
  443. depth = pParent->drawable.depth;
  444. ancwopt = pParent->optional;
  445. if (!ancwopt)
  446. ancwopt = FindWindowWithOptional(pParent)->optional;
  447. if (visual == CopyFromParent) {
  448. visual = ancwopt->visual;
  449. }
  450. /* Find out if the depth and visual are acceptable for this Screen */
  451. if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) {
  452. fOK = FALSE;
  453. for (idepth = 0; idepth < pScreen->numDepths; idepth++) {
  454. pDepth = (DepthPtr) & pScreen->allowedDepths[idepth];
  455. if ((depth == pDepth->depth) || (depth == 0)) {
  456. for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) {
  457. if (visual == pDepth->vids[ivisual]) {
  458. fOK = TRUE;
  459. break;
  460. }
  461. }
  462. }
  463. }
  464. if (fOK == FALSE) {
  465. *error = BadMatch;
  466. return NullWindow;
  467. }
  468. }
  469. if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
  470. (class != InputOnly) && (depth != pParent->drawable.depth)) {
  471. *error = BadMatch;
  472. return NullWindow;
  473. }
  474. if (((vmask & CWColormap) == 0) &&
  475. (class != InputOnly) &&
  476. ((visual != ancwopt->visual) || (ancwopt->colormap == None))) {
  477. *error = BadMatch;
  478. return NullWindow;
  479. }
  480. pWin = AllocateWindow(pScreen);
  481. if (!pWin) {
  482. *error = BadAlloc;
  483. return NullWindow;
  484. }
  485. pWin->drawable = pParent->drawable;
  486. pWin->drawable.depth = depth;
  487. if (depth == pParent->drawable.depth)
  488. pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
  489. else {
  490. for (format = screenInfo.formats; format->depth != depth; format++);
  491. pWin->drawable.bitsPerPixel = format->bitsPerPixel;
  492. }
  493. if (class == InputOnly)
  494. pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
  495. pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  496. pWin->drawable.id = wid;
  497. pWin->drawable.class = class;
  498. pWin->parent = pParent;
  499. SetWindowToDefaults(pWin);
  500. if (visual != ancwopt->visual) {
  501. if (!MakeWindowOptional(pWin)) {
  502. free(pWin);
  503. *error = BadAlloc;
  504. return NullWindow;
  505. }
  506. pWin->optional->visual = visual;
  507. pWin->optional->colormap = None;
  508. }
  509. pWin->borderWidth = bw;
  510. pWin->backgroundState = None;
  511. pWin->borderIsPixel = pParent->borderIsPixel;
  512. pWin->border = pParent->border;
  513. if (pWin->borderIsPixel == FALSE)
  514. pWin->border.pixmap->refcnt++;
  515. pWin->origin.x = x + (int) bw;
  516. pWin->origin.y = y + (int) bw;
  517. pWin->drawable.width = w;
  518. pWin->drawable.height = h;
  519. pWin->drawable.x = pParent->drawable.x + x + (int) bw;
  520. pWin->drawable.y = pParent->drawable.y + y + (int) bw;
  521. /* set up clip list correctly for unobscured WindowPtr */
  522. REGION_NULL(&pWin->clipList);
  523. REGION_NULL(&pWin->borderClip);
  524. REGION_NULL(&pWin->winSize);
  525. REGION_NULL(&pWin->borderSize);
  526. pHead = RealChildHead(pParent);
  527. if (pHead) {
  528. pWin->nextSib = pHead->nextSib;
  529. if (pHead->nextSib)
  530. pHead->nextSib->prevSib = pWin;
  531. else
  532. pParent->lastChild = pWin;
  533. pHead->nextSib = pWin;
  534. pWin->prevSib = pHead;
  535. }
  536. else {
  537. pWin->nextSib = pParent->firstChild;
  538. if (pParent->firstChild)
  539. pParent->firstChild->prevSib = pWin;
  540. else
  541. pParent->lastChild = pWin;
  542. pParent->firstChild = pWin;
  543. }
  544. SetWinSize(pWin);
  545. SetBorderSize(pWin);
  546. /* We SHOULD check for an error value here XXX */
  547. if (!(*pScreen->CreateWindow) (pWin)) {
  548. *error = BadAlloc;
  549. DeleteWindow(pWin, None);
  550. return NullWindow;
  551. }
  552. /* We SHOULD check for an error value here XXX */
  553. (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y);
  554. if (!(vmask & CWEventMask))
  555. RecalculateDeliverableEvents(pWin);
  556. if (vmask)
  557. *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient(pWin));
  558. else
  559. *error = Success;
  560. if (*error != Success) {
  561. DeleteWindow(pWin, None);
  562. return NullWindow;
  563. }
  564. if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful)) {
  565. XID value = defaultBackingStore;
  566. (void) ChangeWindowAttributes(pWin, CWBackingStore, &value,
  567. wClient(pWin));
  568. pWin->forcedBS = TRUE;
  569. }
  570. if (SubSend(pParent)) {
  571. event.u.u.type = CreateNotify;
  572. event.u.createNotify.window = wid;
  573. event.u.createNotify.parent = pParent->drawable.id;
  574. event.u.createNotify.x = x;
  575. event.u.createNotify.y = y;
  576. event.u.createNotify.width = w;
  577. event.u.createNotify.height = h;
  578. event.u.createNotify.borderWidth = bw;
  579. event.u.createNotify.override = pWin->overrideRedirect;
  580. DeliverEvents(pParent, &event, 1, NullWindow);
  581. }
  582. return pWin;
  583. }
  584. static void
  585. FreeWindowResources(register WindowPtr pWin)
  586. {
  587. ScreenPtr pScreen = pWin->drawable.pScreen;
  588. DeleteWindowFromAnySaveSet(pWin);
  589. DeleteWindowFromAnySelections(pWin);
  590. DeleteWindowFromAnyEvents(pWin, TRUE);
  591. REGION_UNINIT(&pWin->clipList);
  592. REGION_UNINIT(&pWin->winSize);
  593. REGION_UNINIT(&pWin->borderClip);
  594. REGION_UNINIT(&pWin->borderSize);
  595. if (wBoundingShape(pWin))
  596. REGION_DESTROY(wBoundingShape(pWin));
  597. if (wClipShape(pWin))
  598. REGION_DESTROY(wClipShape(pWin));
  599. if (wInputShape(pWin))
  600. REGION_DESTROY(wInputShape(pWin));
  601. if (pWin->borderIsPixel == FALSE)
  602. (*pScreen->DestroyPixmap) (pWin->border.pixmap);
  603. if (pWin->backgroundState == BackgroundPixmap)
  604. (*pScreen->DestroyPixmap) (pWin->background.pixmap);
  605. DeleteAllWindowProperties(pWin);
  606. /* We SHOULD check for an error value here XXX */
  607. (*pScreen->DestroyWindow) (pWin);
  608. DisposeWindowOptional(pWin);
  609. }
  610. static void
  611. CrushTree(WindowPtr pWin)
  612. {
  613. WindowPtr pChild, pSib, pParent;
  614. UnrealizeWindowProcPtr UnrealizeWindow;
  615. xEvent event;
  616. if (!(pChild = pWin->firstChild))
  617. return;
  618. UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
  619. while (1) {
  620. if (pChild->firstChild) {
  621. pChild = pChild->firstChild;
  622. continue;
  623. }
  624. while (1) {
  625. pParent = pChild->parent;
  626. if (SubStrSend(pChild, pParent)) {
  627. event.u.u.type = DestroyNotify;
  628. event.u.destroyNotify.window = pChild->drawable.id;
  629. DeliverEvents(pChild, &event, 1, NullWindow);
  630. }
  631. FreeResource(pChild->drawable.id, RT_WINDOW);
  632. pSib = pChild->nextSib;
  633. pChild->viewable = FALSE;
  634. if (pChild->realized) {
  635. pChild->realized = FALSE;
  636. (*UnrealizeWindow) (pChild);
  637. }
  638. FreeWindowResources(pChild);
  639. free(pChild);
  640. if ((pChild = pSib))
  641. break;
  642. pChild = pParent;
  643. pChild->firstChild = NullWindow;
  644. pChild->lastChild = NullWindow;
  645. if (pChild == pWin)
  646. return;
  647. }
  648. }
  649. }
  650. /*****
  651. * DeleteWindow
  652. * Deletes child of window then window itself
  653. * If wid is None, don't send any events
  654. *****/
  655. int
  656. DeleteWindow(pointer value, XID wid)
  657. {
  658. WindowPtr pParent;
  659. WindowPtr pWin = (WindowPtr) value;
  660. xEvent event;
  661. UnmapWindow(pWin, FALSE);
  662. CrushTree(pWin);
  663. pParent = pWin->parent;
  664. if (wid && pParent && SubStrSend(pWin, pParent)) {
  665. event.u.u.type = DestroyNotify;
  666. event.u.destroyNotify.window = pWin->drawable.id;
  667. DeliverEvents(pWin, &event, 1, NullWindow);
  668. }
  669. FreeWindowResources(pWin);
  670. if (pParent) {
  671. if (pParent->firstChild == pWin)
  672. pParent->firstChild = pWin->nextSib;
  673. if (pParent->lastChild == pWin)
  674. pParent->lastChild = pWin->prevSib;
  675. if (pWin->nextSib)
  676. pWin->nextSib->prevSib = pWin->prevSib;
  677. if (pWin->prevSib)
  678. pWin->prevSib->nextSib = pWin->nextSib;
  679. }
  680. free(pWin);
  681. return Success;
  682. }
  683. void
  684. DestroySubwindows(register WindowPtr pWin, ClientPtr client)
  685. {
  686. /* XXX
  687. * The protocol is quite clear that each window should be
  688. * destroyed in turn, however, unmapping all of the first
  689. * eliminates most of the calls to ValidateTree. So,
  690. * this implementation is incorrect in that all of the
  691. * UnmapNotifies occur before all of the DestroyNotifies.
  692. * If you care, simply delete the call to UnmapSubwindows.
  693. */
  694. UnmapSubwindows(pWin);
  695. while (pWin->lastChild)
  696. FreeResource(pWin->lastChild->drawable.id, RT_NONE);
  697. }
  698. #define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
  699. ButtonReleaseMask | PointerMotionMask)
  700. /*****
  701. * ChangeWindowAttributes
  702. *
  703. * The value-mask specifies which attributes are to be changed; the
  704. * value-list contains one value for each one bit in the mask, from least
  705. * to most significant bit in the mask.
  706. *****/
  707. _X_EXPORT int
  708. ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist,
  709. ClientPtr client)
  710. {
  711. Mask index2;
  712. XID *pVlist;
  713. PixmapPtr pPixmap;
  714. Pixmap pixID;
  715. CursorPtr pCursor, pOldCursor;
  716. Cursor cursorID;
  717. WindowPtr pChild;
  718. Colormap cmap;
  719. ColormapPtr pCmap;
  720. xEvent xE;
  721. int result;
  722. ScreenPtr pScreen;
  723. Mask vmaskCopy = 0;
  724. Mask tmask;
  725. unsigned int val;
  726. int error;
  727. Bool checkOptional = FALSE;
  728. Bool borderRelative = FALSE;
  729. if ((pWin->drawable.class == InputOnly) &&
  730. (vmask & (~INPUTONLY_LEGAL_MASK)))
  731. return BadMatch;
  732. error = Success;
  733. pScreen = pWin->drawable.pScreen;
  734. pVlist = vlist;
  735. tmask = vmask;
  736. while (tmask) {
  737. index2 = (Mask) lowbit(tmask);
  738. tmask &= ~index2;
  739. switch (index2) {
  740. case CWBackPixmap:
  741. pixID = (Pixmap) * pVlist;
  742. pVlist++;
  743. if (pWin->backgroundState == ParentRelative)
  744. borderRelative = TRUE;
  745. if (pixID == None) {
  746. if (pWin->backgroundState == BackgroundPixmap)
  747. (*pScreen->DestroyPixmap) (pWin->background.pixmap);
  748. if (!pWin->parent)
  749. MakeRootTile(pWin);
  750. else
  751. pWin->backgroundState = None;
  752. }
  753. else if (pixID == ParentRelative) {
  754. if (pWin->parent &&
  755. pWin->drawable.depth != pWin->parent->drawable.depth) {
  756. error = BadMatch;
  757. goto PatchUp;
  758. }
  759. if (pWin->backgroundState == BackgroundPixmap)
  760. (*pScreen->DestroyPixmap) (pWin->background.pixmap);
  761. if (!pWin->parent)
  762. MakeRootTile(pWin);
  763. else
  764. pWin->backgroundState = ParentRelative;
  765. borderRelative = TRUE;
  766. /* Note that the parent's backgroundTile's refcnt is NOT
  767. * incremented. */
  768. }
  769. else {
  770. pPixmap = (PixmapPtr) SecurityLookupIDByType(client, pixID,
  771. RT_PIXMAP,
  772. SecurityReadAccess);
  773. if (pPixmap != (PixmapPtr) NULL) {
  774. if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
  775. (pPixmap->drawable.pScreen != pScreen)) {
  776. error = BadMatch;
  777. goto PatchUp;
  778. }
  779. if (pWin->backgroundState == BackgroundPixmap)
  780. (*pScreen->DestroyPixmap) (pWin->background.pixmap);
  781. pWin->backgroundState = BackgroundPixmap;
  782. pWin->background.pixmap = pPixmap;
  783. pPixmap->refcnt++;
  784. }
  785. else {
  786. error = BadPixmap;
  787. client->errorValue = pixID;
  788. goto PatchUp;
  789. }
  790. }
  791. break;
  792. case CWBackPixel:
  793. if (pWin->backgroundState == ParentRelative)
  794. borderRelative = TRUE;
  795. if (pWin->backgroundState == BackgroundPixmap)
  796. (*pScreen->DestroyPixmap) (pWin->background.pixmap);
  797. pWin->backgroundState = BackgroundPixel;
  798. pWin->background.pixel = (CARD32) *pVlist;
  799. /* background pixel overrides background pixmap,
  800. so don't let the ddx layer see both bits */
  801. vmaskCopy &= ~CWBackPixmap;
  802. pVlist++;
  803. break;
  804. case CWBorderPixmap:
  805. pixID = (Pixmap) * pVlist;
  806. pVlist++;
  807. if (pixID == CopyFromParent) {
  808. if (!pWin->parent ||
  809. (pWin->drawable.depth != pWin->parent->drawable.depth)) {
  810. error = BadMatch;
  811. goto PatchUp;
  812. }
  813. if (pWin->borderIsPixel == FALSE)
  814. (*pScreen->DestroyPixmap) (pWin->border.pixmap);
  815. pWin->border = pWin->parent->border;
  816. if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE) {
  817. index2 = CWBorderPixel;
  818. }
  819. else {
  820. pWin->parent->border.pixmap->refcnt++;
  821. }
  822. }
  823. else {
  824. pPixmap = (PixmapPtr) SecurityLookupIDByType(client, pixID,
  825. RT_PIXMAP,
  826. SecurityReadAccess);
  827. if (pPixmap) {
  828. if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
  829. (pPixmap->drawable.pScreen != pScreen)) {
  830. error = BadMatch;
  831. goto PatchUp;
  832. }
  833. if (pWin->borderIsPixel == FALSE)
  834. (*pScreen->DestroyPixmap) (pWin->border.pixmap);
  835. pWin->borderIsPixel = FALSE;
  836. pWin->border.pixmap = pPixmap;
  837. pPixmap->refcnt++;
  838. }
  839. else {
  840. error = BadPixmap;
  841. client->errorValue = pixID;
  842. goto PatchUp;
  843. }
  844. }
  845. break;
  846. case CWBorderPixel:
  847. if (pWin->borderIsPixel == FALSE)
  848. (*pScreen->DestroyPixmap) (pWin->border.pixmap);
  849. pWin->borderIsPixel = TRUE;
  850. pWin->border.pixel = (CARD32) *pVlist;
  851. /* border pixel overrides border pixmap,
  852. so don't let the ddx layer see both bits */
  853. vmaskCopy &= ~CWBorderPixmap;
  854. pVlist++;
  855. break;
  856. case CWBitGravity:
  857. val = (CARD8) *pVlist;
  858. pVlist++;
  859. if (val > StaticGravity) {
  860. error = BadValue;
  861. client->errorValue = val;
  862. goto PatchUp;
  863. }
  864. pWin->bitGravity = val;
  865. break;
  866. case CWWinGravity:
  867. val = (CARD8) *pVlist;
  868. pVlist++;
  869. if (val > StaticGravity) {
  870. error = BadValue;
  871. client->errorValue = val;
  872. goto PatchUp;
  873. }
  874. pWin->winGravity = val;
  875. break;
  876. case CWBackingStore:
  877. val = (CARD8) *pVlist;
  878. pVlist++;
  879. if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) {
  880. error = BadValue;
  881. client->errorValue = val;
  882. goto PatchUp;
  883. }
  884. pWin->backingStore = val;
  885. pWin->forcedBS = FALSE;
  886. break;
  887. case CWBackingPlanes:
  888. if (pWin->optional || ((CARD32) *pVlist != (CARD32) ~0L)) {
  889. if (!pWin->optional && !MakeWindowOptional(pWin)) {
  890. error = BadAlloc;
  891. goto PatchUp;
  892. }
  893. pWin->optional->backingBitPlanes = (CARD32) *pVlist;
  894. if ((CARD32) *pVlist == (CARD32) ~0L)
  895. checkOptional = TRUE;
  896. }
  897. pVlist++;
  898. break;
  899. case CWBackingPixel:
  900. if (pWin->optional || (CARD32) *pVlist) {
  901. if (!pWin->optional && !MakeWindowOptional(pWin)) {
  902. error = BadAlloc;
  903. goto PatchUp;
  904. }
  905. pWin->optional->backingPixel = (CARD32) *pVlist;
  906. if (!*pVlist)
  907. checkOptional = TRUE;
  908. }
  909. pVlist++;
  910. break;
  911. case CWSaveUnder:
  912. val = (BOOL) * pVlist;
  913. pVlist++;
  914. if ((val != xTrue) && (val != xFalse)) {
  915. error = BadValue;
  916. client->errorValue = val;
  917. goto PatchUp;
  918. }
  919. pWin->saveUnder = val;
  920. break;
  921. case CWEventMask:
  922. result = EventSelectForWindow(pWin, client, (Mask) *pVlist);
  923. if (result) {
  924. error = result;
  925. goto PatchUp;
  926. }
  927. pVlist++;
  928. break;
  929. case CWDontPropagate:
  930. result = EventSuppressForWindow(pWin, client, (Mask) *pVlist,
  931. &checkOptional);
  932. if (result) {
  933. error = result;
  934. goto PatchUp;
  935. }
  936. pVlist++;
  937. break;
  938. case CWOverrideRedirect:
  939. val = (BOOL) * pVlist;
  940. pVlist++;
  941. if ((val != xTrue) && (val != xFalse)) {
  942. error = BadValue;
  943. client->errorValue = val;
  944. goto PatchUp;
  945. }
  946. pWin->overrideRedirect = val;
  947. break;
  948. case CWColormap:
  949. cmap = (Colormap) * pVlist;
  950. pVlist++;
  951. if (cmap == CopyFromParent) {
  952. if (pWin->parent &&
  953. (!pWin->optional ||
  954. pWin->optional->visual == wVisual(pWin->parent))) {
  955. cmap = wColormap(pWin->parent);
  956. }
  957. else
  958. cmap = None;
  959. }
  960. if (cmap == None) {
  961. error = BadMatch;
  962. goto PatchUp;
  963. }
  964. pCmap = (ColormapPtr) SecurityLookupIDByType(client, cmap,
  965. RT_COLORMAP,
  966. SecurityReadAccess);
  967. if (!pCmap) {
  968. error = BadColor;
  969. client->errorValue = cmap;
  970. goto PatchUp;
  971. }
  972. if (pCmap->pVisual->vid != wVisual(pWin) ||
  973. pCmap->pScreen != pScreen) {
  974. error = BadMatch;
  975. goto PatchUp;
  976. }
  977. if (cmap != wColormap(pWin)) {
  978. if (!pWin->optional) {
  979. if (!MakeWindowOptional(pWin)) {
  980. error = BadAlloc;
  981. goto PatchUp;
  982. }
  983. }
  984. else if (pWin->parent && cmap == wColormap(pWin->parent))
  985. checkOptional = TRUE;
  986. /*
  987. * propagate the original colormap to any children
  988. * inheriting it
  989. */
  990. for (pChild = pWin->firstChild; pChild;
  991. pChild = pChild->nextSib) {
  992. if (!pChild->optional && !MakeWindowOptional(pChild)) {
  993. error = BadAlloc;
  994. goto PatchUp;
  995. }
  996. }
  997. pWin->optional->colormap = cmap;
  998. /*
  999. * check on any children now matching the new colormap
  1000. */
  1001. for (pChild = pWin->firstChild; pChild;
  1002. pChild = pChild->nextSib) {
  1003. if (pChild->optional->colormap == cmap)
  1004. CheckWindowOptionalNeed(pChild);
  1005. }
  1006. xE.u.u.type = ColormapNotify;
  1007. xE.u.colormap.window = pWin->drawable.id;
  1008. xE.u.colormap.colormap = cmap;
  1009. xE.u.colormap.new = xTrue;
  1010. xE.u.colormap.state = IsMapInstalled(cmap, pWin);
  1011. DeliverEvents(pWin, &xE, 1, NullWindow);
  1012. }
  1013. break;
  1014. case CWCursor:
  1015. cursorID = (Cursor) * pVlist;
  1016. pVlist++;
  1017. /*
  1018. * install the new
  1019. */
  1020. if (cursorID == None) {
  1021. if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
  1022. pCursor = rootCursor;
  1023. else
  1024. pCursor = (CursorPtr) None;
  1025. }
  1026. else {
  1027. pCursor = (CursorPtr) SecurityLookupIDByType(client, cursorID,
  1028. RT_CURSOR,
  1029. SecurityReadAccess);
  1030. if (!pCursor) {
  1031. error = BadCursor;
  1032. client->errorValue = cursorID;
  1033. goto PatchUp;
  1034. }
  1035. }
  1036. if (pCursor != wCursor(pWin)) {
  1037. /*
  1038. * patch up child windows so they don't lose cursors.
  1039. */
  1040. for (pChild = pWin->firstChild; pChild;
  1041. pChild = pChild->nextSib) {
  1042. if (!pChild->optional && !pChild->cursorIsNone &&
  1043. !MakeWindowOptional(pChild)) {
  1044. error = BadAlloc;
  1045. goto PatchUp;
  1046. }
  1047. }
  1048. pOldCursor = 0;
  1049. if (pCursor == (CursorPtr) None) {
  1050. pWin->cursorIsNone = TRUE;
  1051. if (pWin->optional) {
  1052. pOldCursor = pWin->optional->cursor;
  1053. pWin->optional->cursor = (CursorPtr) None;
  1054. checkOptional = TRUE;
  1055. }
  1056. }
  1057. else {
  1058. if (!pWin->optional) {
  1059. if (!MakeWindowOptional(pWin)) {
  1060. error = BadAlloc;
  1061. goto PatchUp;
  1062. }
  1063. }
  1064. else if (pWin->parent && pCursor == wCursor(pWin->parent))
  1065. checkOptional = TRUE;
  1066. pOldCursor = pWin->optional->cursor;
  1067. pWin->optional->cursor = pCursor;
  1068. pCursor->refcnt++;
  1069. pWin->cursorIsNone = FALSE;
  1070. /*
  1071. * check on any children now matching the new cursor
  1072. */
  1073. for (pChild = pWin->firstChild; pChild;
  1074. pChild = pChild->nextSib) {
  1075. if (pChild->optional &&
  1076. (pChild->optional->cursor == pCursor))
  1077. CheckWindowOptionalNeed(pChild);
  1078. }
  1079. }
  1080. if (pWin->realized)
  1081. WindowHasNewCursor(pWin);
  1082. /* Can't free cursor until here - old cursor
  1083. * is needed in WindowHasNewCursor
  1084. */
  1085. if (pOldCursor)
  1086. FreeCursor(pOldCursor, (Cursor) 0);
  1087. }
  1088. break;
  1089. default:
  1090. error = BadValue;
  1091. client->errorValue = vmask;
  1092. goto PatchUp;
  1093. }
  1094. vmaskCopy |= index2;
  1095. }
  1096. PatchUp:
  1097. if (checkOptional)
  1098. CheckWindowOptionalNeed(pWin);
  1099. /* We SHOULD check for an error value here XXX */
  1100. (*pScreen->ChangeWindowAttributes) (pWin, vmaskCopy);
  1101. /*
  1102. If the border contents have changed, redraw the border.
  1103. Note that this has to be done AFTER pScreen->ChangeWindowAttributes
  1104. for the tile to be rotated, and the correct function selected.
  1105. */
  1106. if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
  1107. && pWin->viewable && HasBorder(pWin)) {
  1108. RegionRec exposed;
  1109. REGION_NULL(&exposed);
  1110. REGION_SUBTRACT(&exposed, &pWin->borderClip, &pWin->winSize);
  1111. (*pWin->drawable.pScreen->PaintWindowBorder) (pWin, &exposed,
  1112. PW_BORDER);
  1113. REGION_UNINIT(&exposed);
  1114. }
  1115. return error;
  1116. }
  1117. /*****
  1118. * GetWindowAttributes
  1119. * Notice that this is different than ChangeWindowAttributes
  1120. *****/
  1121. void
  1122. GetWindowAttributes(register WindowPtr pWin, ClientPtr client,
  1123. xGetWindowAttributesReply * wa)
  1124. {
  1125. wa->type = X_Reply;
  1126. wa->bitGravity = pWin->bitGravity;
  1127. wa->winGravity = pWin->winGravity;
  1128. if (pWin->forcedBS && pWin->backingStore != Always)
  1129. wa->backingStore = NotUseful;
  1130. else
  1131. wa->backingStore = pWin->backingStore;
  1132. wa->length = (sizeof(xGetWindowAttributesReply) -
  1133. sizeof(xGenericReply)) >> 2;
  1134. wa->sequenceNumber = client->sequence;
  1135. wa->backingBitPlanes = wBackingBitPlanes(pWin);
  1136. wa->backingPixel = wBackingPixel(pWin);
  1137. wa->saveUnder = (BOOL) pWin->saveUnder;
  1138. wa->override = pWin->overrideRedirect;
  1139. if (!pWin->mapped)
  1140. wa->mapState = IsUnmapped;
  1141. else if (pWin->realized)
  1142. wa->mapState = IsViewable;
  1143. else
  1144. wa->mapState = IsUnviewable;
  1145. wa->colormap = wColormap(pWin);
  1146. wa->mapInstalled = (wa->colormap == None) ? xFalse
  1147. : IsMapInstalled(wa->colormap, pWin);
  1148. wa->yourEventMask = EventMaskForClient(pWin, client);
  1149. wa->allEventMasks = pWin->eventMask | wOtherEventMasks(pWin);
  1150. wa->doNotPropagateMask = wDontPropagateMask(pWin);
  1151. wa->class = pWin->drawable.class;
  1152. wa->visualID = wVisual(pWin);
  1153. }
  1154. _X_EXPORT WindowPtr
  1155. MoveWindowInStack(register WindowPtr pWin, register WindowPtr pNextSib)
  1156. {
  1157. WindowPtr pParent = pWin->parent;
  1158. WindowPtr pFirstChange = pWin; /* highest window where list changes */
  1159. if (pWin->nextSib != pNextSib) {
  1160. WindowPtr pOldNextSib = pWin->nextSib;
  1161. if (!pNextSib) { /* move to bottom */
  1162. if (pParent->firstChild == pWin)
  1163. pParent->firstChild = pWin->nextSib;
  1164. /* if (pWin->nextSib) *//* is always True: pNextSib == NULL
  1165. * and pWin->nextSib != pNextSib
  1166. * therefore pWin->nextSib != NULL */
  1167. pFirstChange = pWin->nextSib;
  1168. pWin->nextSib->prevSib = pWin->prevSib;
  1169. if (pWin->prevSib)
  1170. pWin->prevSib->nextSib = pWin->nextSib;
  1171. pParent->lastChild->nextSib = pWin;
  1172. pWin->prevSib = pParent->lastChild;
  1173. pWin->nextSib = NullWindow;
  1174. pParent->lastChild = pWin;
  1175. }
  1176. else if (pParent->firstChild == pNextSib) { /* move to top */
  1177. pFirstChange = pWin;
  1178. if (pParent->lastChild == pWin)
  1179. pParent->lastChild = pWin->prevSib;
  1180. if (pWin->nextSib)
  1181. pWin->nextSib->prevSib = pWin->prevSib;
  1182. if (pWin->prevSib)
  1183. pWin->prevSib->nextSib = pWin->nextSib;
  1184. pWin->nextSib = pParent->firstChild;
  1185. pWin->prevSib = (WindowPtr) NULL;
  1186. pNextSib->prevSib = pWin;
  1187. pParent->firstChild = pWin;
  1188. }
  1189. else { /* move in middle of list */
  1190. WindowPtr pOldNext = pWin->nextSib;
  1191. pFirstChange = NullWindow;
  1192. if (pParent->firstChild == pWin)
  1193. pFirstChange = pParent->firstChild = pWin->nextSib;
  1194. if (pParent->lastChild == pWin) {
  1195. pFirstChange = pWin;
  1196. pParent->lastChild = pWin->prevSib;
  1197. }
  1198. if (pWin->nextSib)
  1199. pWin->nextSib->prevSib = pWin->prevSib;
  1200. if (pWin->prevSib)
  1201. pWin->prevSib->nextSib = pWin->nextSib;
  1202. pWin->nextSib = pNextSib;
  1203. pWin->prevSib = pNextSib->prevSib;
  1204. if (pNextSib->prevSib)
  1205. pNextSib->prevSib->nextSib = pWin;
  1206. pNextSib->prevSib = pWin;
  1207. if (!pFirstChange) { /* do we know it yet? */
  1208. pFirstChange = pParent->firstChild; /* no, search from top */
  1209. while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
  1210. pFirstChange = pFirstChange->nextSib;
  1211. }
  1212. }
  1213. if (pWin->drawable.pScreen->RestackWindow)
  1214. (*pWin->drawable.pScreen->RestackWindow) (pWin, pOldNextSib);
  1215. }
  1216. return (pFirstChange);
  1217. }
  1218. _X_EXPORT void
  1219. SetWinSize(register WindowPtr pWin)
  1220. {
  1221. ClippedRegionFromBox(pWin->parent, &pWin->winSize,
  1222. pWin->drawable.x, pWin->drawable.y,
  1223. (int) pWin->drawable.width,
  1224. (int) pWin->drawable.height);
  1225. if (wBoundingShape(pWin) || wClipShape(pWin)) {
  1226. REGION_TRANSLATE(&pWin->winSize, -pWin->drawable.x,
  1227. -pWin->drawable.y);
  1228. if (wBoundingShape(pWin))
  1229. REGION_INTERSECT(&pWin->winSize, &pWin->winSize,
  1230. wBoundingShape(pWin));
  1231. if (wClipShape(pWin))
  1232. REGION_INTERSECT(&pWin->winSize, &pWin->winSize,
  1233. wClipShape(pWin));
  1234. REGION_TRANSLATE(&pWin->winSize, pWin->drawable.x,
  1235. pWin->drawable.y);
  1236. }
  1237. }
  1238. _X_EXPORT void
  1239. SetBorderSize(register WindowPtr pWin)
  1240. {
  1241. int bw;
  1242. if (HasBorder(pWin)) {
  1243. bw = wBorderWidth(pWin);
  1244. ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
  1245. pWin->drawable.x - bw, pWin->drawable.y - bw,
  1246. (int) (pWin->drawable.width + (bw << 1)),
  1247. (int) (pWin->drawable.height + (bw << 1)));
  1248. if (wBoundingShape(pWin)) {
  1249. REGION_TRANSLATE(&pWin->borderSize, -pWin->drawable.x,
  1250. -pWin->drawable.y);
  1251. REGION_INTERSECT(&pWin->borderSize, &pWin->borderSize,
  1252. wBoundingShape(pWin));
  1253. REGION_TRANSLATE(&pWin->borderSize, pWin->drawable.x,
  1254. pWin->drawable.y);
  1255. REGION_UNION(&pWin->borderSize, &pWin->borderSize,
  1256. &pWin->winSize);
  1257. }
  1258. }
  1259. else {
  1260. REGION_COPY(&pWin->borderSize, &pWin->winSize);
  1261. }
  1262. }
  1263. /**
  1264. *
  1265. * \param x,y new window position
  1266. * \param oldx,oldy old window position
  1267. * \param destx,desty position relative to gravity
  1268. */
  1269. _X_EXPORT void
  1270. GravityTranslate(register int x, register int y, int oldx, int oldy,
  1271. int dw, int dh, unsigned gravity,
  1272. register int *destx, register int *desty)
  1273. {
  1274. switch (gravity) {
  1275. case NorthGravity:
  1276. *destx = x + dw / 2;
  1277. *desty = y;
  1278. break;
  1279. case NorthEastGravity:
  1280. *destx = x + dw;
  1281. *desty = y;
  1282. break;
  1283. case WestGravity:
  1284. *destx = x;
  1285. *desty = y + dh / 2;
  1286. break;
  1287. case CenterGravity:
  1288. *destx = x + dw / 2;
  1289. *desty = y + dh / 2;
  1290. break;
  1291. case EastGravity:
  1292. *destx = x + dw;
  1293. *desty = y + dh / 2;
  1294. break;
  1295. case SouthWestGravity:
  1296. *destx = x;
  1297. *desty = y + dh;
  1298. break;
  1299. case SouthGravity:
  1300. *destx = x + dw / 2;
  1301. *desty = y + dh;
  1302. break;
  1303. case SouthEastGravity:
  1304. *destx = x + dw;
  1305. *desty = y + dh;
  1306. break;
  1307. case StaticGravity:
  1308. *destx = oldx;
  1309. *desty = oldy;
  1310. break;
  1311. default:
  1312. *destx = x;
  1313. *desty = y;
  1314. break;
  1315. }
  1316. }
  1317. /* XXX need to retile border on each window with ParentRelative origin */
  1318. _X_EXPORT void
  1319. ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
  1320. {
  1321. ScreenPtr pScreen;
  1322. WindowPtr pSib, pChild;
  1323. Bool resized = (dw || dh);
  1324. pScreen = pWin->drawable.pScreen;
  1325. for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib) {
  1326. if (resized && (pSib->winGravity > NorthWestGravity)) {
  1327. int cwsx, cwsy;
  1328. cwsx = pSib->origin.x;
  1329. cwsy = pSib->origin.y;
  1330. GravityTranslate(cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
  1331. pSib->winGravity, &cwsx, &cwsy);
  1332. if (cwsx != pSib->origin.x || cwsy != pSib->origin.y) {
  1333. xEvent event;
  1334. event.u.u.type = GravityNotify;
  1335. event.u.gravity.window = pSib->drawable.id;
  1336. event.u.gravity.x = cwsx - wBorderWidth(pSib);
  1337. event.u.gravity.y = cwsy - wBorderWidth(pSib);
  1338. DeliverEvents(pSib, &event, 1, NullWindow);
  1339. pSib->origin.x = cwsx;
  1340. pSib->origin.y = cwsy;
  1341. }
  1342. }
  1343. pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
  1344. pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
  1345. SetWinSize(pSib);
  1346. SetBorderSize(pSib);
  1347. (*pScreen->PositionWindow) (pSib, pSib->drawable.x, pSib->drawable.y);
  1348. if ((pChild = pSib->firstChild)) {
  1349. while (1) {
  1350. pChild->drawable.x = pChild->parent->drawable.x +
  1351. pChild->origin.x;
  1352. pChild->drawable.y = pChild->parent->drawable.y +
  1353. pChild->origin.y;
  1354. SetWinSize(pChild);
  1355. SetBorderSize(pChild);
  1356. (*pScreen->PositionWindow) (pChild,
  1357. pChild->drawable.x,
  1358. pChild->drawable.y);
  1359. if (pChild->firstChild) {
  1360. pChild = pChild->firstChild;
  1361. continue;
  1362. }
  1363. while (!pChild->nextSib && (pChild != pSib))
  1364. pChild = pChild->parent;
  1365. if (pChild == pSib)
  1366. break;
  1367. pChild = pChild->nextSib;
  1368. }
  1369. }
  1370. }
  1371. }
  1372. #define GET_INT16(m, f) \
  1373. if (m & mask) \
  1374. { \
  1375. f = (INT16) *pVlist;\
  1376. pVlist++; \
  1377. }
  1378. #define GET_CARD16(m, f) \
  1379. if (m & mask) \
  1380. { \
  1381. f = (CARD16) *pVlist;\
  1382. pVlist++;\
  1383. }
  1384. #define GET_CARD8(m, f) \
  1385. if (m & mask) \
  1386. { \
  1387. f = (CARD8) *pVlist;\
  1388. pVlist++;\
  1389. }
  1390. #define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
  1391. #define IllegalInputOnlyConfigureMask (CWBorderWidth)
  1392. /*
  1393. * IsSiblingAboveMe
  1394. * returns Above if pSib above pMe in stack or Below otherwise
  1395. */
  1396. static int
  1397. IsSiblingAboveMe(register WindowPtr pMe, register WindowPtr pSib)
  1398. {
  1399. WindowPtr pWin;
  1400. pWin = pMe->parent->firstChild;
  1401. while (pWin) {
  1402. if (pWin == pSib)
  1403. return (Above);
  1404. else if (pWin == pMe)
  1405. return (Below);
  1406. pWin = pWin->nextSib;
  1407. }
  1408. return (Below);
  1409. }
  1410. static BoxPtr
  1411. WindowExtents(register WindowPtr pWin, register BoxPtr pBox)
  1412. {
  1413. pBox->x1 = pWin->drawable.x - wBorderWidth(pWin);
  1414. pBox->y1 = pWin->drawable.y - wBorderWidth(pWin);
  1415. pBox->x2 = pWin->drawable.x + (int) pWin->drawable.width
  1416. + wBorderWidth(pWin);
  1417. pBox->y2 = pWin->drawable.y + (int) pWin->drawable.height
  1418. + wBorderWidth(pWin);
  1419. return (pBox);
  1420. }
  1421. #define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
  1422. static RegionPtr
  1423. MakeBoundingRegion(register WindowPtr pWin, BoxPtr pBox)
  1424. {
  1425. RegionPtr pRgn;
  1426. pRgn = REGION_CREATE(pBox, 1);
  1427. if (wBoundingShape(pWin)) {
  1428. REGION_TRANSLATE(pRgn, -pWin->origin.x, -pWin->origin.y);
  1429. REGION_INTERSECT(pRgn, pRgn, wBoundingShape(pWin));
  1430. REGION_TRANSLATE(pRgn, pWin->origin.x, pWin->origin.y);
  1431. }
  1432. return pRgn;
  1433. }
  1434. static Bool
  1435. ShapeOverlap(WindowPtr pWin, BoxPtr pWinBox, WindowPtr pSib, BoxPtr pSibBox)
  1436. {
  1437. RegionPtr pWinRgn, pSibRgn;
  1438. Bool ret;
  1439. if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
  1440. return TRUE;
  1441. pWinRgn = MakeBoundingRegion(pWin, pWinBox);
  1442. pSibRgn = MakeBoundingRegion(pSib, pSibBox);
  1443. REGION_INTERSECT(pWinRgn, pWinRgn, pSibRgn);
  1444. ret = REGION_NOTEMPTY(pWinRgn);
  1445. REGION_DESTROY(pWinRgn);
  1446. REGION_DESTROY(pSibRgn);
  1447. return ret;
  1448. }
  1449. static Bool
  1450. AnyWindowOverlapsMe(WindowPtr pWin, WindowPtr pHead, register BoxPtr box)
  1451. {
  1452. WindowPtr pSib;
  1453. BoxRec sboxrec;
  1454. BoxPtr sbox;
  1455. for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib) {
  1456. if (pSib->mapped) {
  1457. sbox = WindowExtents(pSib, &sboxrec);
  1458. if (BOXES_OVERLAP(sbox, box)
  1459. && ShapeOverlap(pWin, box, pSib, sbox)
  1460. )
  1461. return (TRUE);
  1462. }
  1463. }
  1464. return (FALSE);
  1465. }
  1466. static Bool
  1467. IOverlapAnyWindow(WindowPtr pWin, register BoxPtr box)
  1468. {
  1469. WindowPtr pSib;
  1470. BoxRec sboxrec;
  1471. BoxPtr sbox;
  1472. for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib) {
  1473. if (pSib->mapped) {
  1474. sbox = WindowExtents(pSib, &sboxrec);
  1475. if (BOXES_OVERLAP(sbox, box)
  1476. && ShapeOverlap(pWin, box, pSib, sbox)
  1477. )
  1478. return (TRUE);
  1479. }
  1480. }
  1481. return (FALSE);
  1482. }
  1483. /*
  1484. * WhereDoIGoInTheStack()
  1485. * Given pWin and pSib and the relationshipe smode, return
  1486. * the window that pWin should go ABOVE.
  1487. * If a pSib is specified:
  1488. * Above: pWin is placed just above pSib
  1489. * Below: pWin is placed just below pSib
  1490. * TopIf: if pSib occludes pWin, then pWin is placed
  1491. * at the top of the stack
  1492. * BottomIf: if pWin occludes pSib, then pWin is
  1493. * placed at the bottom of the stack
  1494. * Opposite: if pSib occludes pWin, then pWin is placed at the
  1495. * top of the stack, else if pWin occludes pSib, then
  1496. * pWin is placed at the bottom of the stack
  1497. *
  1498. * If pSib is NULL:
  1499. * Above: pWin is placed at the top of the stack
  1500. * Below: pWin is placed at the bottom of the stack
  1501. * TopIf: if any sibling occludes pWin, then pWin is placed at
  1502. * the top of the stack
  1503. * BottomIf: if pWin occludes any sibline, then pWin is placed at
  1504. * the bottom of the stack
  1505. * Opposite: if any sibling occludes pWin, then pWin is placed at
  1506. * the top of the stack, else if pWin occludes any
  1507. * sibling, then pWin is placed at the bottom of the stack
  1508. *
  1509. */
  1510. static WindowPtr
  1511. WhereDoIGoInTheStack(register WindowPtr pWin,
  1512. register WindowPtr pSib,
  1513. short x,
  1514. short y, unsigned short w, unsigned short h, int smode)
  1515. {
  1516. BoxRec box;
  1517. WindowPtr pHead, pFirst;
  1518. if ((pWin == pWin->parent->firstChild) && (pWin == pWin->parent->lastChild))
  1519. return ((WindowPtr) NULL);
  1520. pHead = RealChildHead(pWin->parent);
  1521. pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
  1522. box.x1 = x;
  1523. box.y1 = y;
  1524. box.x2 = x + (int) w;
  1525. box.y2 = y + (int) h;
  1526. switch (smode) {
  1527. case Above:
  1528. if (pSib)
  1529. return (pSib);
  1530. else if (pWin == pFirst)
  1531. return (pWin->nextSib);
  1532. else
  1533. return (pFirst);
  1534. case Below:
  1535. if (pSib)
  1536. if (pSib->nextSib != pWin)
  1537. return (pSib->nextSib);
  1538. else
  1539. return (pWin->nextSib);
  1540. else
  1541. return NullWindow;
  1542. case TopIf:
  1543. if ((!pWin->mapped || (pSib && !pSib->mapped)))
  1544. return (pWin->nextSib);
  1545. else if (pSib) {
  1546. if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
  1547. (RECT_IN_REGION(&pSib->borderSize, &box) != rgnOUT))
  1548. return (pFirst);
  1549. else
  1550. return (pWin->nextSib);
  1551. }
  1552. else if (AnyWindowOverlapsMe(pWin, pHead, &box))
  1553. return (pFirst);
  1554. else
  1555. return (pWin->nextSib);
  1556. case BottomIf:
  1557. if ((!pWin->mapped || (pSib && !pSib->mapped)))
  1558. return (pWin->nextSib);
  1559. else if (pSib) {
  1560. if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
  1561. (RECT_IN_REGION(&pSib->borderSize, &box) != rgnOUT))
  1562. return NullWindow;
  1563. else
  1564. return (pWin->nextSib);
  1565. }
  1566. else if (IOverlapAnyWindow(pWin, &box))
  1567. return NullWindow;
  1568. else
  1569. return (pWin->nextSib);
  1570. case Opposite:
  1571. if ((!pWin->mapped || (pSib && !pSib->mapped)))
  1572. return (pWin->nextSib);
  1573. else if (pSib) {
  1574. if (RECT_IN_REGION(&pSib->borderSize, &box) != rgnOUT) {
  1575. if (IsSiblingAboveMe(pWin, pSib) == Above)
  1576. return (pFirst);
  1577. else
  1578. return NullWindow;
  1579. }
  1580. else
  1581. return (pWin->nextSib);
  1582. }
  1583. else if (AnyWindowOverlapsMe(pWin, pHead, &box)) {
  1584. /* If I'm occluded, I can't possibly be the first child
  1585. * if (pWin == pWin->parent->firstChild)
  1586. * return pWin->nextSib;
  1587. */
  1588. return (pFirst);
  1589. }
  1590. else if (IOverlapAnyWindow(pWin, &box))
  1591. return NullWindow;
  1592. else
  1593. return pWin->nextSib;
  1594. default:
  1595. {
  1596. ErrorF("Internal error in ConfigureWindow, smode == %d\n", smode);
  1597. return pWin->nextSib;
  1598. }
  1599. }
  1600. }
  1601. static void
  1602. ReflectStackChange(register WindowPtr pWin,
  1603. register WindowPtr pSib, VTKind kind)
  1604. {
  1605. /* Note that pSib might be NULL */
  1606. Bool WasViewable = (Bool) pWin->viewable;
  1607. Bool anyMarked;
  1608. WindowPtr pFirstChange;
  1609. WindowPtr pLayerWin;
  1610. ScreenPtr pScreen = pWin->drawable.pScreen;
  1611. /* if this is a root window, can't be restacked */
  1612. if (!pWin->parent)
  1613. return;
  1614. pFirstChange = MoveWindowInStack(pWin, pSib);
  1615. if (WasViewable) {
  1616. anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange,
  1617. &pLayerWin);
  1618. if (pLayerWin != pWin)
  1619. pFirstChange = pLayerWin;
  1620. if (anyMarked) {
  1621. (*pScreen->ValidateTree) (pLayerWin->parent, pFirstChange, kind);
  1622. (*pScreen->HandleExposures) (pLayerWin->parent);
  1623. }
  1624. if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
  1625. (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstChange,
  1626. kind);
  1627. }
  1628. if (pWin->realized)
  1629. WindowsRestructured();
  1630. }
  1631. /*****
  1632. * ConfigureWindow
  1633. *****/
  1634. int
  1635. ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist,
  1636. ClientPtr client)
  1637. {
  1638. #define RESTACK_WIN 0
  1639. #define MOVE_WIN 1
  1640. #define RESIZE_WIN 2
  1641. #define REBORDER_WIN 3
  1642. WindowPtr pSib = NullWindow;
  1643. WindowPtr pParent = pWin->parent;
  1644. Window sibwid = 0;
  1645. Mask index2, tmask;
  1646. XID *pVlist;
  1647. short x, y, beforeX, beforeY;
  1648. unsigned short w = pWin->drawable.width,
  1649. h = pWin->drawable.height, bw = pWin->borderWidth;
  1650. int action, smode = Above;
  1651. xEvent event;
  1652. if ((pWin->drawable.class == InputOnly) &&
  1653. (mask & IllegalInputOnlyConfigureMask))
  1654. return (BadMatch);
  1655. if ((mask & CWSibling) && !(mask & CWStackMode))
  1656. return (BadMatch);
  1657. pVlist = vlist;
  1658. if (pParent) {
  1659. x = pWin->drawable.x - pParent->drawable.x - (int) bw;
  1660. y = pWin->drawable.y - pParent->drawable.y - (int) bw;
  1661. }
  1662. else {
  1663. x = pWin->drawable.x;
  1664. y = pWin->drawable.y;
  1665. }
  1666. beforeX = x;
  1667. beforeY = y;
  1668. action = RESTACK_WIN;
  1669. if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth)))) {
  1670. GET_INT16(CWX, x);
  1671. GET_INT16(CWY, y);
  1672. action = MOVE_WIN;
  1673. }
  1674. /* or should be resized */
  1675. else if (mask & (CWX | CWY | CWWidth | CWHeight)) {
  1676. GET_INT16(CWX, x);
  1677. GET_INT16(CWY, y);
  1678. GET_CARD16(CWWidth, w);
  1679. GET_CARD16(CWHeight, h);
  1680. if (!w || !h) {
  1681. client->errorValue = 0;
  1682. return BadValue;
  1683. }
  1684. action = RESIZE_WIN;
  1685. }
  1686. tmask = mask & ~ChangeMask;
  1687. while (tmask) {
  1688. index2 = (Mask) lowbit(tmask);
  1689. tmask &= ~index2;
  1690. switch (index2) {
  1691. case CWBorderWidth:
  1692. GET_CARD16(CWBorderWidth, bw);
  1693. break;
  1694. case CWSibling:
  1695. sibwid = (Window) *pVlist;
  1696. pVlist++;
  1697. pSib = (WindowPtr) SecurityLookupIDByType(client, sibwid,
  1698. RT_WINDOW,
  1699. SecurityReadAccess);
  1700. if (!pSib) {
  1701. client->errorValue = sibwid;
  1702. return (BadWindow);
  1703. }
  1704. if (pSib->parent != pParent)
  1705. return (BadMatch);
  1706. if (pSib == pWin)
  1707. return (BadMatch);
  1708. break;
  1709. case CWStackMode:
  1710. GET_CARD8(CWStackMode, smode);
  1711. if ((smode != TopIf) && (smode != BottomIf) &&
  1712. (smode != Opposite) && (smode != Above) && (smode != Below)) {
  1713. client->errorValue = smode;
  1714. return (BadValue);
  1715. }
  1716. break;
  1717. default:
  1718. client->errorValue = mask;
  1719. return (BadValue);
  1720. }
  1721. }
  1722. /* root really can't be reconfigured, so just return */
  1723. if (!pParent)
  1724. return Success;
  1725. /* Figure out if the window should be moved. Doesnt
  1726. make the changes to the window if event sent */
  1727. if (mask & CWStackMode)
  1728. pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
  1729. pParent->drawable.y + y,
  1730. w + (bw << 1), h + (bw << 1), smode);
  1731. else
  1732. pSib = pWin->nextSib;
  1733. if ((!pWin->overrideRedirect) && (RedirectSend(pParent)
  1734. )) {
  1735. event.u.u.type = ConfigureRequest;
  1736. event.u.configureRequest.window = pWin->drawable.id;
  1737. if (mask & CWSibling)
  1738. event.u.configureRequest.sibling = sibwid;
  1739. else
  1740. event.u.configureRequest.sibling = None;
  1741. if (mask & CWStackMode)
  1742. event.u.u.detail = smode;
  1743. else
  1744. event.u.u.detail = Above;
  1745. event.u.configureRequest.x = x;
  1746. event.u.configureRequest.y = y;
  1747. event.u.configureRequest.width = w;
  1748. event.u.configureRequest.height = h;
  1749. event.u.configureRequest.borderWidth = bw;
  1750. event.u.configureRequest.valueMask = mask;
  1751. event.u.configureRequest.parent = pParent->drawable.id;
  1752. if (MaybeDeliverEventsToClient(pParent, &event, 1,
  1753. SubstructureRedirectMask, client) == 1)
  1754. return (Success);
  1755. }
  1756. if (action == RESIZE_WIN) {
  1757. Bool size_change = (w != pWin->drawable.width)
  1758. || (h != pWin->drawable.height);
  1759. if (size_change &&
  1760. ((pWin->eventMask | wOtherEventMasks(pWin)) & ResizeRedirectMask)) {
  1761. xEvent eventT;
  1762. eventT.u.u.type = ResizeRequest;
  1763. eventT.u.resizeRequest.window = pWin->drawable.id;
  1764. eventT.u.resizeRequest.width = w;
  1765. eventT.u.resizeRequest.height = h;
  1766. if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
  1767. ResizeRedirectMask, client) == 1) {
  1768. /* if event is delivered, leave the actual size alone. */
  1769. w = pWin->drawable.width;
  1770. h = pWin->drawable.height;
  1771. size_change = FALSE;
  1772. }
  1773. }
  1774. if (!size_change) {
  1775. if (mask & (CWX | CWY))
  1776. action = MOVE_WIN;
  1777. else if (mask & (CWStackMode | CWBorderWidth))
  1778. action = RESTACK_WIN;
  1779. else /* really nothing to do */
  1780. return (Success);
  1781. }
  1782. }
  1783. if (action == RESIZE_WIN)
  1784. /* we've already checked whether there's really a size change */
  1785. goto ActuallyDoSomething;
  1786. if ((mask & CWX) && (x != beforeX))
  1787. goto ActuallyDoSomething;
  1788. if ((mask & CWY) && (y != beforeY))
  1789. goto ActuallyDoSomething;
  1790. if ((mask & CWBorderWidth) && (bw != wBorderWidth(pWin)))
  1791. goto ActuallyDoSomething;
  1792. if (mask & CWStackMode) {
  1793. /* See above for why we always reorder in rootless mode. */
  1794. if (pWin->nextSib != pSib)
  1795. goto ActuallyDoSomething;
  1796. }
  1797. return (Success);
  1798. ActuallyDoSomething:
  1799. if (SubStrSend(pWin, pParent)) {
  1800. event.u.u.type = ConfigureNotify;
  1801. event.u.configureNotify.window = pWin->drawable.id;
  1802. if (pSib)
  1803. event.u.configureNotify.aboveSibling = pSib->drawable.id;
  1804. else
  1805. event.u.configureNotify.aboveSibling = None;
  1806. event.u.configureNotify.x = x;
  1807. event.u.configureNotify.y = y;
  1808. event.u.configureNotify.width = w;
  1809. event.u.configureNotify.height = h;
  1810. event.u.configureNotify.borderWidth = bw;
  1811. event.u.configureNotify.override = pWin->overrideRedirect;
  1812. DeliverEvents(pWin, &event, 1, NullWindow);
  1813. }
  1814. if (mask & CWBorderWidth) {
  1815. if (action == RESTACK_WIN) {
  1816. action = MOVE_WIN;
  1817. pWin->borderWidth = bw;
  1818. }
  1819. else if ((action == MOVE_WIN) &&
  1820. (beforeX + wBorderWidth(pWin) == x + (int) bw) &&
  1821. (beforeY + wBorderWidth(pWin) == y + (int) bw)) {
  1822. action = REBORDER_WIN;
  1823. (*pWin->drawable.pScreen->ChangeBorderWidth) (pWin, bw);
  1824. }
  1825. else
  1826. pWin->borderWidth = bw;
  1827. }
  1828. if (action == MOVE_WIN)
  1829. (*pWin->drawable.pScreen->MoveWindow) (pWin, x, y, pSib,
  1830. (mask & CWBorderWidth) ? VTOther
  1831. : VTMove);
  1832. else if (action == RESIZE_WIN)
  1833. (*pWin->drawable.pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
  1834. else if (mask & CWStackMode)
  1835. ReflectStackChange(pWin, pSib, VTOther);
  1836. if (action != RESTACK_WIN)
  1837. CheckCursorConfinement(pWin);
  1838. return (Success);
  1839. #undef RESTACK_WIN
  1840. #undef MOVE_WIN
  1841. #undef RESIZE_WIN
  1842. #undef REBORDER_WIN
  1843. }
  1844. /******
  1845. *
  1846. * CirculateWindow
  1847. * For RaiseLowest, raises the lowest mapped child (if any) that is
  1848. * obscured by another child to the top of the stack. For LowerHighest,
  1849. * lowers the highest mapped child (if any) that is obscuring another
  1850. * child to the bottom of the stack. Exposure processing is performed
  1851. *
  1852. ******/
  1853. int
  1854. CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
  1855. {
  1856. WindowPtr pWin, pHead, pFirst;
  1857. xEvent event;
  1858. BoxRec box;
  1859. pHead = RealChildHead(pParent);
  1860. pFirst = pHead ? pHead->nextSib : pParent->firstChild;
  1861. if (direction == RaiseLowest) {
  1862. for (pWin = pParent->lastChild;
  1863. (pWin != pHead) &&
  1864. !(pWin->mapped &&
  1865. AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
  1866. pWin = pWin->prevSib);
  1867. if (pWin == pHead)
  1868. return Success;
  1869. }
  1870. else {
  1871. for (pWin = pFirst;
  1872. pWin &&
  1873. !(pWin->mapped &&
  1874. IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
  1875. pWin = pWin->nextSib);
  1876. if (!pWin)
  1877. return Success;
  1878. }
  1879. event.u.circulate.window = pWin->drawable.id;
  1880. event.u.circulate.parent = pParent->drawable.id;
  1881. event.u.circulate.event = pParent->drawable.id;
  1882. if (direction == RaiseLowest)
  1883. event.u.circulate.place = PlaceOnTop;
  1884. else
  1885. event.u.circulate.place = PlaceOnBottom;
  1886. if (RedirectSend(pParent)) {
  1887. event.u.u.type = CirculateRequest;
  1888. if (MaybeDeliverEventsToClient(pParent, &event, 1,
  1889. SubstructureRedirectMask, client) == 1)
  1890. return (Success);
  1891. }
  1892. event.u.u.type = CirculateNotify;
  1893. DeliverEvents(pWin, &event, 1, NullWindow);
  1894. ReflectStackChange(pWin,
  1895. (direction == RaiseLowest) ? pFirst : NullWindow,
  1896. VTStack);
  1897. return (Success);
  1898. }
  1899. static int
  1900. CompareWIDs(WindowPtr pWin, pointer value)
  1901. { /* must conform to VisitWindowProcPtr */
  1902. Window *wid = (Window *) value;
  1903. if (pWin->drawable.id == *wid)
  1904. return (WT_STOPWALKING);
  1905. else
  1906. return (WT_WALKCHILDREN);
  1907. }
  1908. /*****
  1909. * ReparentWindow
  1910. *****/
  1911. int
  1912. ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
  1913. int x, int y, ClientPtr client)
  1914. {
  1915. WindowPtr pPrev, pPriorParent;
  1916. Bool WasMapped = (Bool) (pWin->mapped);
  1917. xEvent event;
  1918. int bw = wBorderWidth(pWin);
  1919. ScreenPtr pScreen;
  1920. pScreen = pWin->drawable.pScreen;
  1921. if (TraverseTree(pWin, CompareWIDs, (pointer) &pParent->drawable.id) ==
  1922. WT_STOPWALKING)
  1923. return (BadMatch);
  1924. if (!MakeWindowOptional(pWin))
  1925. return (BadAlloc);
  1926. if (WasMapped)
  1927. UnmapWindow(pWin, FALSE);
  1928. event.u.u.type = ReparentNotify;
  1929. event.u.reparent.window = pWin->drawable.id;
  1930. event.u.reparent.parent = pParent->drawable.id;
  1931. event.u.reparent.x = x;
  1932. event.u.reparent.y = y;
  1933. event.u.reparent.override = pWin->overrideRedirect;
  1934. DeliverEvents(pWin, &event, 1, pParent);
  1935. /* take out of sibling chain */
  1936. pPriorParent = pPrev = pWin->parent;
  1937. if (pPrev->firstChild == pWin)
  1938. pPrev->firstChild = pWin->nextSib;
  1939. if (pPrev->lastChild == pWin)
  1940. pPrev->lastChild = pWin->prevSib;
  1941. if (pWin->nextSib)
  1942. pWin->nextSib->prevSib = pWin->prevSib;
  1943. if (pWin->prevSib)
  1944. pWin->prevSib->nextSib = pWin->nextSib;
  1945. /* insert at begining of pParent */
  1946. pWin->parent = pParent;
  1947. pPrev = RealChildHead(pParent);
  1948. if (pPrev) {
  1949. pWin->nextSib = pPrev->nextSib;
  1950. if (pPrev->nextSib)
  1951. pPrev->nextSib->prevSib = pWin;
  1952. else
  1953. pParent->lastChild = pWin;
  1954. pPrev->nextSib = pWin;
  1955. pWin->prevSib = pPrev;
  1956. }
  1957. else {
  1958. pWin->nextSib = pParent->firstChild;
  1959. pWin->prevSib = NullWindow;
  1960. if (pParent->firstChild)
  1961. pParent->firstChild->prevSib = pWin;
  1962. else
  1963. pParent->lastChild = pWin;
  1964. pParent->firstChild = pWin;
  1965. }
  1966. pWin->origin.x = x + bw;
  1967. pWin->origin.y = y + bw;
  1968. pWin->drawable.x = x + bw + pParent->drawable.x;
  1969. pWin->drawable.y = y + bw + pParent->drawable.y;
  1970. /* clip to parent */
  1971. SetWinSize(pWin);
  1972. SetBorderSize(pWin);
  1973. if (pScreen->ReparentWindow)
  1974. (*pScreen->ReparentWindow) (pWin, pPriorParent);
  1975. (*pScreen->PositionWindow) (pWin, pWin->drawable.x, pWin->drawable.y);
  1976. ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
  1977. CheckWindowOptionalNeed(pWin);
  1978. if (WasMapped)
  1979. MapWindow(pWin, client);
  1980. RecalculateDeliverableEvents(pWin);
  1981. return (Success);
  1982. }
  1983. static void
  1984. RealizeTree(WindowPtr pWin)
  1985. {
  1986. WindowPtr pChild;
  1987. RealizeWindowProcPtr Realize;
  1988. Realize = pWin->drawable.pScreen->RealizeWindow;
  1989. pChild = pWin;
  1990. while (1) {
  1991. if (pChild->mapped) {
  1992. pChild->realized = TRUE;
  1993. pChild->viewable = (pChild->drawable.class == InputOutput);
  1994. (*Realize) (pChild);
  1995. if (pChild->firstChild) {
  1996. pChild = pChild->firstChild;
  1997. continue;
  1998. }
  1999. }
  2000. while (!pChild->nextSib && (pChild != pWin))
  2001. pChild = pChild->parent;
  2002. if (pChild == pWin)
  2003. return;
  2004. pChild = pChild->nextSib;
  2005. }
  2006. }
  2007. /*****
  2008. * MapWindow
  2009. * If some other client has selected SubStructureReDirect on the parent
  2010. * and override-redirect is xFalse, then a MapRequest event is generated,
  2011. * but the window remains unmapped. Otherwise, the window is mapped and a
  2012. * MapNotify event is generated.
  2013. *****/
  2014. _X_EXPORT int
  2015. MapWindow(register WindowPtr pWin, ClientPtr client)
  2016. {
  2017. ScreenPtr pScreen;
  2018. WindowPtr pParent;
  2019. WindowPtr pLayerWin;
  2020. if (pWin->mapped)
  2021. return (Success);
  2022. pScreen = pWin->drawable.pScreen;
  2023. if ((pParent = pWin->parent)) {
  2024. xEvent event;
  2025. Bool anyMarked;
  2026. if ((!pWin->overrideRedirect) && (RedirectSend(pParent)
  2027. )) {
  2028. event.u.u.type = MapRequest;
  2029. event.u.mapRequest.window = pWin->drawable.id;
  2030. event.u.mapRequest.parent = pParent->drawable.id;
  2031. if (MaybeDeliverEventsToClient(pParent, &event, 1,
  2032. SubstructureRedirectMask,
  2033. client) == 1)
  2034. return (Success);
  2035. }
  2036. pWin->mapped = TRUE;
  2037. if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin)) {
  2038. event.u.u.type = MapNotify;
  2039. event.u.mapNotify.window = pWin->drawable.id;
  2040. event.u.mapNotify.override = pWin->overrideRedirect;
  2041. DeliverEvents(pWin, &event, 1, NullWindow);
  2042. }
  2043. if (!pParent->realized)
  2044. return (Success);
  2045. RealizeTree(pWin);
  2046. if (pWin->viewable) {
  2047. anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin,
  2048. &pLayerWin);
  2049. if (anyMarked) {
  2050. (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTMap);
  2051. (*pScreen->HandleExposures) (pLayerWin->parent);
  2052. }
  2053. if (anyMarked && pScreen->PostValidateTree)
  2054. (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin,
  2055. VTMap);
  2056. }
  2057. WindowsRestructured();
  2058. }
  2059. else {
  2060. RegionRec temp;
  2061. pWin->mapped = TRUE;
  2062. pWin->realized = TRUE; /* for roots */
  2063. pWin->viewable = pWin->drawable.class == InputOutput;
  2064. /* We SHOULD check for an error value here XXX */
  2065. (*pScreen->RealizeWindow) (pWin);
  2066. if (pScreen->ClipNotify)
  2067. (*pScreen->ClipNotify) (pWin, 0, 0);
  2068. if (pScreen->PostValidateTree)
  2069. (*pScreen->PostValidateTree) (NullWindow, pWin, VTMap);
  2070. REGION_NULL(&temp);
  2071. REGION_COPY(&temp, &pWin->clipList);
  2072. (*pScreen->WindowExposures) (pWin, &temp, NullRegion);
  2073. REGION_UNINIT(&temp);
  2074. }
  2075. return (Success);
  2076. }
  2077. /*****
  2078. * MapSubwindows
  2079. * Performs a MapWindow all unmapped children of the window, in top
  2080. * to bottom stacking order.
  2081. *****/
  2082. void
  2083. MapSubwindows(register WindowPtr pParent, ClientPtr client)
  2084. {
  2085. WindowPtr pWin;
  2086. WindowPtr pFirstMapped = NullWindow;
  2087. ScreenPtr pScreen;
  2088. Mask parentRedirect;
  2089. Mask parentNotify;
  2090. xEvent event;
  2091. Bool anyMarked;
  2092. WindowPtr pLayerWin;
  2093. pScreen = pParent->drawable.pScreen;
  2094. parentRedirect = RedirectSend(pParent);
  2095. parentNotify = SubSend(pParent);
  2096. anyMarked = FALSE;
  2097. for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib) {
  2098. if (!pWin->mapped) {
  2099. if (parentRedirect && !pWin->overrideRedirect) {
  2100. event.u.u.type = MapRequest;
  2101. event.u.mapRequest.window = pWin->drawable.id;
  2102. event.u.mapRequest.parent = pParent->drawable.id;
  2103. if (MaybeDeliverEventsToClient(pParent, &event, 1,
  2104. SubstructureRedirectMask,
  2105. client) == 1)
  2106. continue;
  2107. }
  2108. pWin->mapped = TRUE;
  2109. if (parentNotify || StrSend(pWin)) {
  2110. event.u.u.type = MapNotify;
  2111. event.u.mapNotify.window = pWin->drawable.id;
  2112. event.u.mapNotify.override = pWin->overrideRedirect;
  2113. DeliverEvents(pWin, &event, 1, NullWindow);
  2114. }
  2115. if (!pFirstMapped)
  2116. pFirstMapped = pWin;
  2117. if (pParent->realized) {
  2118. RealizeTree(pWin);
  2119. if (pWin->viewable) {
  2120. anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin,
  2121. (WindowPtr
  2122. *) NULL);
  2123. }
  2124. }
  2125. }
  2126. }
  2127. if (pFirstMapped) {
  2128. pLayerWin = (*pScreen->GetLayerWindow) (pParent);
  2129. if (pLayerWin->parent != pParent) {
  2130. anyMarked |= (*pScreen->MarkOverlappedWindows) (pLayerWin,
  2131. pLayerWin,
  2132. (WindowPtr *) NULL);
  2133. pFirstMapped = pLayerWin;
  2134. }
  2135. if (anyMarked) {
  2136. (*pScreen->ValidateTree) (pLayerWin->parent, pFirstMapped, VTMap);
  2137. (*pScreen->HandleExposures) (pLayerWin->parent);
  2138. }
  2139. if (anyMarked && pScreen->PostValidateTree)
  2140. (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstMapped,
  2141. VTMap);
  2142. WindowsRestructured();
  2143. }
  2144. }
  2145. static void
  2146. UnrealizeTree(WindowPtr pWin, Bool fromConfigure)
  2147. {
  2148. WindowPtr pChild;
  2149. UnrealizeWindowProcPtr Unrealize;
  2150. MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
  2151. Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
  2152. MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
  2153. pChild = pWin;
  2154. while (1) {
  2155. if (pChild->realized) {
  2156. pChild->realized = FALSE;
  2157. pChild->visibility = VisibilityNotViewable;
  2158. (*Unrealize) (pChild);
  2159. DeleteWindowFromAnyEvents(pChild, FALSE);
  2160. if (pChild->viewable) {
  2161. pChild->viewable = FALSE;
  2162. (*MarkUnrealizedWindow) (pChild, pWin, fromConfigure);
  2163. pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  2164. }
  2165. if (pChild->firstChild) {
  2166. pChild = pChild->firstChild;
  2167. continue;
  2168. }
  2169. }
  2170. while (!pChild->nextSib && (pChild != pWin))
  2171. pChild = pChild->parent;
  2172. if (pChild == pWin)
  2173. return;
  2174. pChild = pChild->nextSib;
  2175. }
  2176. }
  2177. /*****
  2178. * UnmapWindow
  2179. * If the window is already unmapped, this request has no effect.
  2180. * Otherwise, the window is unmapped and an UnMapNotify event is
  2181. * generated. Cannot unmap a root window.
  2182. *****/
  2183. _X_EXPORT int
  2184. UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
  2185. {
  2186. WindowPtr pParent;
  2187. xEvent event;
  2188. Bool wasRealized = (Bool) pWin->realized;
  2189. Bool wasViewable = (Bool) pWin->viewable;
  2190. ScreenPtr pScreen = pWin->drawable.pScreen;
  2191. WindowPtr pLayerWin = pWin;
  2192. if ((!pWin->mapped) || (!(pParent = pWin->parent)))
  2193. return (Success);
  2194. if (SubStrSend(pWin, pParent) && MapUnmapEventsEnabled(pWin)) {
  2195. event.u.u.type = UnmapNotify;
  2196. event.u.unmapNotify.window = pWin->drawable.id;
  2197. event.u.unmapNotify.fromConfigure = fromConfigure;
  2198. DeliverEvents(pWin, &event, 1, NullWindow);
  2199. }
  2200. if (wasViewable && !fromConfigure) {
  2201. pWin->valdata = UnmapValData;
  2202. (*pScreen->MarkOverlappedWindows) (pWin, pWin->nextSib, &pLayerWin);
  2203. (*pScreen->MarkWindow) (pLayerWin->parent);
  2204. }
  2205. pWin->mapped = FALSE;
  2206. if (wasRealized)
  2207. UnrealizeTree(pWin, fromConfigure);
  2208. if (wasViewable) {
  2209. if (!fromConfigure) {
  2210. (*pScreen->ValidateTree) (pLayerWin->parent, pWin, VTUnmap);
  2211. (*pScreen->HandleExposures) (pLayerWin->parent);
  2212. }
  2213. if (!fromConfigure && pScreen->PostValidateTree)
  2214. (*pScreen->PostValidateTree) (pLayerWin->parent, pWin, VTUnmap);
  2215. }
  2216. if (wasRealized && !fromConfigure)
  2217. WindowsRestructured();
  2218. return (Success);
  2219. }
  2220. /*****
  2221. * UnmapSubwindows
  2222. * Performs an UnmapWindow request with the specified mode on all mapped
  2223. * children of the window, in bottom to top stacking order.
  2224. *****/
  2225. void
  2226. UnmapSubwindows(register WindowPtr pWin)
  2227. {
  2228. WindowPtr pChild, pHead;
  2229. xEvent event;
  2230. Bool wasRealized = (Bool) pWin->realized;
  2231. Bool wasViewable = (Bool) pWin->viewable;
  2232. Bool anyMarked = FALSE;
  2233. Mask parentNotify;
  2234. WindowPtr pLayerWin = NULL;
  2235. ScreenPtr pScreen = pWin->drawable.pScreen;
  2236. if (!pWin->firstChild)
  2237. return;
  2238. parentNotify = SubSend(pWin);
  2239. pHead = RealChildHead(pWin);
  2240. if (wasViewable)
  2241. pLayerWin = (*pScreen->GetLayerWindow) (pWin);
  2242. for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) {
  2243. if (pChild->mapped) {
  2244. if (parentNotify || StrSend(pChild)) {
  2245. event.u.u.type = UnmapNotify;
  2246. event.u.unmapNotify.window = pChild->drawable.id;
  2247. event.u.unmapNotify.fromConfigure = xFalse;
  2248. DeliverEvents(pChild, &event, 1, NullWindow);
  2249. }
  2250. if (pChild->viewable) {
  2251. pChild->valdata = UnmapValData;
  2252. anyMarked = TRUE;
  2253. }
  2254. pChild->mapped = FALSE;
  2255. if (pChild->realized)
  2256. UnrealizeTree(pChild, FALSE);
  2257. if (wasViewable) {
  2258. }
  2259. }
  2260. }
  2261. if (wasViewable) {
  2262. if (anyMarked) {
  2263. if (pLayerWin->parent == pWin)
  2264. (*pScreen->MarkWindow) (pWin);
  2265. else {
  2266. WindowPtr ptmp;
  2267. (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin,
  2268. (WindowPtr *) NULL);
  2269. (*pScreen->MarkWindow) (pLayerWin->parent);
  2270. /* Windows between pWin and pLayerWin may not have been marked */
  2271. ptmp = pWin;
  2272. while (ptmp != pLayerWin->parent) {
  2273. (*pScreen->MarkWindow) (ptmp);
  2274. ptmp = ptmp->parent;
  2275. }
  2276. pHead = pWin->firstChild;
  2277. }
  2278. (*pScreen->ValidateTree) (pLayerWin->parent, pHead, VTUnmap);
  2279. (*pScreen->HandleExposures) (pLayerWin->parent);
  2280. }
  2281. if (anyMarked && pScreen->PostValidateTree)
  2282. (*pScreen->PostValidateTree) (pLayerWin->parent, pHead, VTUnmap);
  2283. }
  2284. if (wasRealized)
  2285. WindowsRestructured();
  2286. }
  2287. void
  2288. HandleSaveSet(register ClientPtr client)
  2289. {
  2290. WindowPtr pParent, pWin;
  2291. int j;
  2292. for (j = 0; j < client->numSaved; j++) {
  2293. pWin = SaveSetWindow(client->saveSet[j]);
  2294. if (SaveSetToRoot(client->saveSet[j]))
  2295. pParent = WindowTable[pWin->drawable.pScreen->myNum];
  2296. else
  2297. {
  2298. pParent = pWin->parent;
  2299. while (pParent && (wClient(pParent) == client))
  2300. pParent = pParent->parent;
  2301. }
  2302. if (pParent) {
  2303. if (pParent != pWin->parent) {
  2304. ReparentWindow(pWin, pParent,
  2305. pWin->drawable.x - wBorderWidth(pWin) -
  2306. pParent->drawable.x,
  2307. pWin->drawable.y - wBorderWidth(pWin) -
  2308. pParent->drawable.y, client);
  2309. if (!pWin->realized && pWin->mapped)
  2310. pWin->mapped = FALSE;
  2311. }
  2312. if (SaveSetRemap(client->saveSet[j]))
  2313. MapWindow(pWin, client);
  2314. }
  2315. }
  2316. free(client->saveSet);
  2317. client->numSaved = 0;
  2318. client->saveSet = (SaveSetElt *) NULL;
  2319. }
  2320. /**
  2321. *
  2322. * \param x,y in root
  2323. * \param box "return" value
  2324. */
  2325. Bool
  2326. VisibleBoundingBoxFromPoint(register WindowPtr pWin, int x, int y, BoxPtr box)
  2327. {
  2328. if (!pWin->realized)
  2329. return (FALSE);
  2330. if (POINT_IN_REGION(&pWin->clipList, x, y, box))
  2331. return (TRUE);
  2332. return (FALSE);
  2333. }
  2334. /**
  2335. *
  2336. * \param x,y in root
  2337. */
  2338. Bool
  2339. PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
  2340. {
  2341. BoxRec box;
  2342. if (!pWin->realized)
  2343. return (FALSE);
  2344. if (POINT_IN_REGION(&pWin->borderClip, x, y, &box)
  2345. && (!wInputShape(pWin) ||
  2346. POINT_IN_REGION(
  2347. wInputShape(pWin),
  2348. x - pWin->drawable.x, y - pWin->drawable.y, &box)))
  2349. return (TRUE);
  2350. return (FALSE);
  2351. }
  2352. _X_EXPORT RegionPtr
  2353. NotClippedByChildren(register WindowPtr pWin)
  2354. {
  2355. RegionPtr pReg;
  2356. pReg = REGION_CREATE(NullBox, 1);
  2357. if (pWin->parent ||
  2358. screenIsSaved != SCREEN_SAVER_ON ||
  2359. !HasSaverWindow(pWin->drawable.pScreen->myNum)) {
  2360. REGION_INTERSECT(pReg, &pWin->borderClip, &pWin->winSize);
  2361. }
  2362. return (pReg);
  2363. }
  2364. _X_EXPORT void
  2365. SendVisibilityNotify(WindowPtr pWin)
  2366. {
  2367. xEvent event;
  2368. #ifndef NO_XINERAMA_PORT
  2369. unsigned int visibility = pWin->visibility;
  2370. #endif
  2371. event.u.u.type = VisibilityNotify;
  2372. event.u.visibility.window = pWin->drawable.id;
  2373. event.u.visibility.state = visibility;
  2374. DeliverEvents(pWin, &event, 1, NullWindow);
  2375. }
  2376. static WindowPtr windowDisableMapUnmapEvents;
  2377. void
  2378. DisableMapUnmapEvents(WindowPtr pWin)
  2379. {
  2380. assert(windowDisableMapUnmapEvents == NULL);
  2381. windowDisableMapUnmapEvents = pWin;
  2382. }
  2383. void
  2384. EnableMapUnmapEvents(WindowPtr pWin)
  2385. {
  2386. assert(windowDisableMapUnmapEvents != NULL);
  2387. windowDisableMapUnmapEvents = NULL;
  2388. }
  2389. Bool
  2390. MapUnmapEventsEnabled(WindowPtr pWin)
  2391. {
  2392. return pWin != windowDisableMapUnmapEvents;
  2393. }
  2394. #define RANDOM_WIDTH 32
  2395. #ifndef NOLOGOHACK
  2396. static void DrawLogo(WindowPtr pWin);
  2397. #endif
  2398. _X_EXPORT void
  2399. SaveScreens(int on, int mode)
  2400. {
  2401. int i;
  2402. int what;
  2403. int type;
  2404. if (on == SCREEN_SAVER_FORCER) {
  2405. UpdateCurrentTimeIf();
  2406. lastDeviceEventTime = currentTime;
  2407. if (mode == ScreenSaverReset)
  2408. what = SCREEN_SAVER_OFF;
  2409. else
  2410. what = SCREEN_SAVER_ON;
  2411. type = what;
  2412. }
  2413. else {
  2414. what = on;
  2415. type = what;
  2416. if (what == screenIsSaved)
  2417. type = SCREEN_SAVER_CYCLE;
  2418. }
  2419. for (i = 0; i < screenInfo.numScreens; i++) {
  2420. if (on == SCREEN_SAVER_FORCER)
  2421. (*screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
  2422. if (savedScreenInfo[i].ExternalScreenSaver) {
  2423. if ((*savedScreenInfo[i].ExternalScreenSaver)
  2424. (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
  2425. continue;
  2426. }
  2427. if (type == screenIsSaved)
  2428. continue;
  2429. switch (type) {
  2430. case SCREEN_SAVER_OFF:
  2431. if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED) {
  2432. (*screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
  2433. what);
  2434. }
  2435. else if (HasSaverWindow(i)) {
  2436. savedScreenInfo[i].pWindow = NullWindow;
  2437. FreeResource(savedScreenInfo[i].wid, RT_NONE);
  2438. }
  2439. break;
  2440. case SCREEN_SAVER_CYCLE:
  2441. if (savedScreenInfo[i].blanked == SCREEN_IS_TILED) {
  2442. WindowPtr pWin = savedScreenInfo[i].pWindow;
  2443. /* make it look like screen saver is off, so that
  2444. * NotClippedByChildren will compute a clip list
  2445. * for the root window, so miPaintWindow works
  2446. */
  2447. screenIsSaved = SCREEN_SAVER_OFF;
  2448. #ifndef NOLOGOHACK
  2449. if (logoScreenSaver)
  2450. (*pWin->drawable.pScreen->ClearToBackground) (pWin, 0, 0, 0,
  2451. 0, FALSE);
  2452. #endif
  2453. (*pWin->drawable.pScreen->MoveWindow) (pWin,
  2454. (short) (-
  2455. (rand() %
  2456. RANDOM_WIDTH)),
  2457. (short) (-
  2458. (rand() %
  2459. RANDOM_WIDTH)),
  2460. pWin->nextSib, VTMove);
  2461. #ifndef NOLOGOHACK
  2462. if (logoScreenSaver)
  2463. DrawLogo(pWin);
  2464. #endif
  2465. screenIsSaved = SCREEN_SAVER_ON;
  2466. }
  2467. /*
  2468. * Call the DDX saver in case it wants to do something
  2469. * at cycle time
  2470. */
  2471. else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED) {
  2472. (*screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
  2473. type);
  2474. }
  2475. break;
  2476. case SCREEN_SAVER_ON:
  2477. if (ScreenSaverBlanking != DontPreferBlanking) {
  2478. if ((*screenInfo.screens[i]->SaveScreen)
  2479. (screenInfo.screens[i], what)) {
  2480. savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
  2481. continue;
  2482. }
  2483. if ((ScreenSaverAllowExposures != DontAllowExposures) &&
  2484. TileScreenSaver(i, SCREEN_IS_BLACK)) {
  2485. savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
  2486. continue;
  2487. }
  2488. }
  2489. if ((ScreenSaverAllowExposures != DontAllowExposures) &&
  2490. TileScreenSaver(i, SCREEN_IS_TILED)) {
  2491. savedScreenInfo[i].blanked = SCREEN_IS_TILED;
  2492. }
  2493. else
  2494. savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
  2495. break;
  2496. }
  2497. }
  2498. screenIsSaved = what;
  2499. if (mode == ScreenSaverReset)
  2500. SetScreenSaverTimer();
  2501. }
  2502. static Bool
  2503. TileScreenSaver(int i, int kind)
  2504. {
  2505. int j;
  2506. int result;
  2507. XID attributes[3];
  2508. Mask mask;
  2509. WindowPtr pWin;
  2510. CursorMetricRec cm;
  2511. unsigned char *srcbits, *mskbits;
  2512. CursorPtr cursor;
  2513. XID cursorID = 0;
  2514. int attri;
  2515. mask = 0;
  2516. attri = 0;
  2517. switch (kind) {
  2518. case SCREEN_IS_TILED:
  2519. switch (WindowTable[i]->backgroundState) {
  2520. case BackgroundPixel:
  2521. attributes[attri++] = WindowTable[i]->background.pixel;
  2522. mask |= CWBackPixel;
  2523. break;
  2524. case BackgroundPixmap:
  2525. attributes[attri++] = None;
  2526. mask |= CWBackPixmap;
  2527. break;
  2528. default:
  2529. break;
  2530. }
  2531. break;
  2532. case SCREEN_IS_BLACK:
  2533. attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
  2534. mask |= CWBackPixel;
  2535. break;
  2536. }
  2537. mask |= CWOverrideRedirect;
  2538. attributes[attri++] = xTrue;
  2539. /*
  2540. * create a blank cursor
  2541. */
  2542. cm.width = 16;
  2543. cm.height = 16;
  2544. cm.xhot = 8;
  2545. cm.yhot = 8;
  2546. srcbits = malloc(BitmapBytePad(32) * 16);
  2547. mskbits = malloc(BitmapBytePad(32) * 16);
  2548. if (!srcbits || !mskbits) {
  2549. free(srcbits);
  2550. free(mskbits);
  2551. cursor = 0;
  2552. }
  2553. else {
  2554. for (j = 0; j < BitmapBytePad(32) * 16; j++)
  2555. srcbits[j] = mskbits[j] = 0x0;
  2556. cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
  2557. if (cursor) {
  2558. cursorID = FakeClientID(0);
  2559. if (AddResource(cursorID, RT_CURSOR, (pointer) cursor)) {
  2560. attributes[attri] = cursorID;
  2561. mask |= CWCursor;
  2562. }
  2563. else
  2564. cursor = 0;
  2565. }
  2566. else {
  2567. free(srcbits);
  2568. free(mskbits);
  2569. }
  2570. }
  2571. pWin = savedScreenInfo[i].pWindow =
  2572. CreateWindow(savedScreenInfo[i].wid,
  2573. WindowTable[i],
  2574. -RANDOM_WIDTH, -RANDOM_WIDTH,
  2575. (unsigned short) screenInfo.screens[i]->width +
  2576. RANDOM_WIDTH,
  2577. (unsigned short) screenInfo.screens[i]->height +
  2578. RANDOM_WIDTH, 0, InputOutput, mask, attributes, 0,
  2579. serverClient, wVisual(WindowTable[i]), &result);
  2580. if (cursor)
  2581. FreeResource(cursorID, RT_NONE);
  2582. if (!pWin)
  2583. return FALSE;
  2584. if (!AddResource(pWin->drawable.id, RT_WINDOW,
  2585. (pointer) savedScreenInfo[i].pWindow))
  2586. return FALSE;
  2587. if (mask & CWBackPixmap) {
  2588. MakeRootTile(pWin);
  2589. (*pWin->drawable.pScreen->ChangeWindowAttributes) (pWin, CWBackPixmap);
  2590. }
  2591. MapWindow(pWin, serverClient);
  2592. #ifndef NOLOGOHACK
  2593. if (kind == SCREEN_IS_TILED && logoScreenSaver)
  2594. DrawLogo(pWin);
  2595. #endif
  2596. return TRUE;
  2597. }
  2598. /*
  2599. * FindWindowWithOptional
  2600. *
  2601. * search ancestors of the given window for an entry containing
  2602. * a WindowOpt structure. Assumptions: some parent will
  2603. * contain the structure.
  2604. */
  2605. _X_EXPORT WindowPtr
  2606. FindWindowWithOptional(register WindowPtr w)
  2607. {
  2608. do
  2609. w = w->parent;
  2610. while (!w->optional);
  2611. return w;
  2612. }
  2613. /*
  2614. * CheckWindowOptionalNeed
  2615. *
  2616. * check each optional entry in the given window to see if
  2617. * the value is satisfied by the default rules. If so,
  2618. * release the optional record
  2619. */
  2620. _X_EXPORT void
  2621. CheckWindowOptionalNeed(register WindowPtr w)
  2622. {
  2623. WindowOptPtr optional;
  2624. WindowOptPtr parentOptional;
  2625. if (!w->parent)
  2626. return;
  2627. optional = w->optional;
  2628. if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
  2629. return;
  2630. if (optional->otherEventMasks != 0)
  2631. return;
  2632. if (optional->otherClients != NULL)
  2633. return;
  2634. if (optional->passiveGrabs != NULL)
  2635. return;
  2636. if (optional->userProps != NULL)
  2637. return;
  2638. if (optional->backingBitPlanes != ~0L)
  2639. return;
  2640. if (optional->backingPixel != 0)
  2641. return;
  2642. if (optional->boundingShape != NULL)
  2643. return;
  2644. if (optional->clipShape != NULL)
  2645. return;
  2646. if (optional->inputShape != NULL)
  2647. return;
  2648. parentOptional = FindWindowWithOptional(w)->optional;
  2649. if (optional->visual != parentOptional->visual)
  2650. return;
  2651. if (optional->cursor != None &&
  2652. (optional->cursor != parentOptional->cursor || w->parent->cursorIsNone))
  2653. return;
  2654. if (optional->colormap != parentOptional->colormap)
  2655. return;
  2656. DisposeWindowOptional(w);
  2657. }
  2658. /*
  2659. * MakeWindowOptional
  2660. *
  2661. * create an optional record and initialize it with the default
  2662. * values.
  2663. */
  2664. _X_EXPORT Bool
  2665. MakeWindowOptional(register WindowPtr pWin)
  2666. {
  2667. WindowOptPtr optional;
  2668. WindowOptPtr parentOptional;
  2669. if (pWin->optional)
  2670. return TRUE;
  2671. optional = malloc(sizeof(WindowOptRec));
  2672. if (!optional)
  2673. return FALSE;
  2674. optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
  2675. optional->otherEventMasks = 0;
  2676. optional->otherClients = NULL;
  2677. optional->passiveGrabs = NULL;
  2678. optional->userProps = NULL;
  2679. optional->backingBitPlanes = ~0L;
  2680. optional->backingPixel = 0;
  2681. optional->boundingShape = NULL;
  2682. optional->clipShape = NULL;
  2683. optional->inputShape = NULL;
  2684. parentOptional = FindWindowWithOptional(pWin)->optional;
  2685. optional->visual = parentOptional->visual;
  2686. if (!pWin->cursorIsNone) {
  2687. optional->cursor = parentOptional->cursor;
  2688. optional->cursor->refcnt++;
  2689. }
  2690. else {
  2691. optional->cursor = None;
  2692. }
  2693. optional->colormap = parentOptional->colormap;
  2694. pWin->optional = optional;
  2695. return TRUE;
  2696. }
  2697. void
  2698. DisposeWindowOptional(register WindowPtr pWin)
  2699. {
  2700. if (!pWin->optional)
  2701. return;
  2702. /*
  2703. * everything is peachy. Delete the optional record
  2704. * and clean up
  2705. */
  2706. /*
  2707. * TOG changed this code to:
  2708. *
  2709. * if (pWin->cursorIsNone == FALSE)
  2710. * FreeCursor (pWin->optional->cursor, (Cursor)0);
  2711. * pWin->cursorIsNone = TRUE;
  2712. *
  2713. * This is blatently wrong; windows without optionals can have
  2714. * two different cursor values, either None or sharing their
  2715. * parents cursor. This difference is controlled by the
  2716. * cursorIsNone value; when TRUE, the window has no cursor,
  2717. * when false, it shares its cursor with its parent; TOG
  2718. * made it impossible for a window to have a cursor without
  2719. * an optional record.
  2720. */
  2721. if (pWin->optional->cursor) {
  2722. FreeCursor(pWin->optional->cursor, (Cursor) 0);
  2723. pWin->cursorIsNone = FALSE;
  2724. }
  2725. else
  2726. pWin->cursorIsNone = TRUE;
  2727. free(pWin->optional);
  2728. pWin->optional = NULL;
  2729. }
  2730. #ifndef NOLOGOHACK
  2731. static void
  2732. DrawLogo(WindowPtr pWin)
  2733. {
  2734. DrawablePtr pDraw;
  2735. ScreenPtr pScreen;
  2736. int x, y;
  2737. unsigned int width, height, size;
  2738. GC *pGC;
  2739. int thin, gap, d31;
  2740. DDXPointRec poly[4];
  2741. ChangeGCVal fore[2], back[2];
  2742. xrgb rgb[2];
  2743. BITS32 fmask, bmask;
  2744. ColormapPtr cmap;
  2745. pDraw = (DrawablePtr) pWin;
  2746. pScreen = pDraw->pScreen;
  2747. x = -pWin->origin.x;
  2748. y = -pWin->origin.y;
  2749. width = pScreen->width;
  2750. height = pScreen->height;
  2751. pGC = GetScratchGC(pScreen->rootDepth, pScreen);
  2752. if (!pGC)
  2753. return;
  2754. if ((rand() % 100) <= 17) /* make the probability for white fairly low */
  2755. fore[0].val = pScreen->whitePixel;
  2756. else
  2757. fore[0].val = pScreen->blackPixel;
  2758. if ((pWin->backgroundState == BackgroundPixel) &&
  2759. (cmap = (ColormapPtr) LookupIDByType(wColormap(pWin), RT_COLORMAP))) {
  2760. Pixel querypixels[2];
  2761. querypixels[0] = fore[0].val;
  2762. querypixels[1] = pWin->background.pixel;
  2763. QueryColors(cmap, 2, querypixels, rgb);
  2764. if ((rgb[0].red == rgb[1].red) &&
  2765. (rgb[0].green == rgb[1].green) && (rgb[0].blue == rgb[1].blue)) {
  2766. if (fore[0].val == pScreen->blackPixel)
  2767. fore[0].val = pScreen->whitePixel;
  2768. else
  2769. fore[0].val = pScreen->blackPixel;
  2770. }
  2771. }
  2772. fore[1].val = FillSolid;
  2773. fmask = GCForeground | GCFillStyle;
  2774. if (pWin->backgroundState == BackgroundPixel) {
  2775. back[0].val = pWin->background.pixel;
  2776. back[1].val = FillSolid;
  2777. bmask = GCForeground | GCFillStyle;
  2778. }
  2779. else {
  2780. back[0].val = 0;
  2781. back[1].val = 0;
  2782. dixChangeGC(NullClient, pGC, GCTileStipXOrigin | GCTileStipYOrigin,
  2783. NULL, back);
  2784. back[0].val = FillTiled;
  2785. back[1].ptr = pWin->background.pixmap;
  2786. bmask = GCFillStyle | GCTile;
  2787. }
  2788. /* should be the same as the reference function XmuDrawLogo() */
  2789. size = width;
  2790. if (height < width)
  2791. size = height;
  2792. size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
  2793. size &= ~1;
  2794. x += rand() % (width - size);
  2795. y += rand() % (height - size);
  2796. /*
  2797. * Draw what will be the thin strokes.
  2798. *
  2799. * -----
  2800. * / /
  2801. * / /
  2802. * / /
  2803. * / /
  2804. * /____/
  2805. * d
  2806. *
  2807. * Point d is 9/44 (~1/5) of the way across.
  2808. */
  2809. thin = (size / 11);
  2810. if (thin < 1)
  2811. thin = 1;
  2812. gap = (thin + 3) / 4;
  2813. d31 = thin + thin + gap;
  2814. poly[0].x = x + size;
  2815. poly[0].y = y;
  2816. poly[1].x = x + size - d31;
  2817. poly[1].y = y;
  2818. poly[2].x = x + 0;
  2819. poly[2].y = y + size;
  2820. poly[3].x = x + d31;
  2821. poly[3].y = y + size;
  2822. dixChangeGC(NullClient, pGC, fmask, NULL, fore);
  2823. ValidateGC(pDraw, pGC);
  2824. (*pGC->ops->FillPolygon) (pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
  2825. /*
  2826. * Erase area not needed for lower thin stroke.
  2827. *
  2828. * ------
  2829. * / /
  2830. * / __ /
  2831. * / / /
  2832. * / / /
  2833. * /__/__/
  2834. */
  2835. poly[0].x = x + d31 / 2;
  2836. poly[0].y = y + size;
  2837. poly[1].x = x + size / 2;
  2838. poly[1].y = y + size / 2;
  2839. poly[2].x = x + (size / 2) + (d31 - (d31 / 2));
  2840. poly[2].y = y + size / 2;
  2841. poly[3].x = x + d31;
  2842. poly[3].y = y + size;
  2843. dixChangeGC(NullClient, pGC, bmask, NULL, back);
  2844. ValidateGC(pDraw, pGC);
  2845. (*pGC->ops->FillPolygon) (pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
  2846. /*
  2847. * Erase area not needed for upper thin stroke.
  2848. *
  2849. * ------
  2850. * / / /
  2851. * /--/ /
  2852. * / /
  2853. * / /
  2854. * /_____/
  2855. */
  2856. poly[0].x = x + size - d31 / 2;
  2857. poly[0].y = y;
  2858. poly[1].x = x + size / 2;
  2859. poly[1].y = y + size / 2;
  2860. poly[2].x = x + (size / 2) - (d31 - (d31 / 2));
  2861. poly[2].y = y + size / 2;
  2862. poly[3].x = x + size - d31;
  2863. poly[3].y = y;
  2864. ValidateGC(pDraw, pGC);
  2865. (*pGC->ops->FillPolygon) (pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
  2866. /*
  2867. * Draw thick stroke.
  2868. * Point b is 1/4 of the way across.
  2869. *
  2870. * b
  2871. * -----
  2872. * \ \
  2873. * \ \
  2874. * \ \
  2875. * \ \
  2876. * \____\
  2877. */
  2878. poly[0].x = x;
  2879. poly[0].y = y;
  2880. poly[1].x = x + size / 4;
  2881. poly[1].y = y;
  2882. poly[2].x = x + size;
  2883. poly[2].y = y + size;
  2884. poly[3].x = x + size - size / 4;
  2885. poly[3].y = y + size;
  2886. dixChangeGC(NullClient, pGC, fmask, NULL, fore);
  2887. ValidateGC(pDraw, pGC);
  2888. (*pGC->ops->FillPolygon) (pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
  2889. /*
  2890. * Erase to create gap.
  2891. *
  2892. * /
  2893. * /
  2894. * /
  2895. * /
  2896. * /
  2897. */
  2898. poly[0].x = x + size - thin;
  2899. poly[0].y = y;
  2900. poly[1].x = x + size - (thin + gap);
  2901. poly[1].y = y;
  2902. poly[2].x = x + thin;
  2903. poly[2].y = y + size;
  2904. poly[3].x = x + thin + gap;
  2905. poly[3].y = y + size;
  2906. dixChangeGC(NullClient, pGC, bmask, NULL, back);
  2907. ValidateGC(pDraw, pGC);
  2908. (*pGC->ops->FillPolygon) (pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
  2909. FreeScratchGC(pGC);
  2910. }
  2911. #endif