WmFunction.c 106 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /*
  24. * (c) Copyright 1989, 1990, 1991, 1992, 1993, 1994 OPEN SOFTWARE FOUNDATION, INC.
  25. * ALL RIGHTS RESERVED
  26. */
  27. /*
  28. * Motif Release 1.2.4
  29. */
  30. /*
  31. * (c) Copyright 1987, 1988, 1989, 1990, 1993, 1994 HEWLETT-PACKARD COMPANY
  32. * (c) Copyright 1993, 1994 International Business Machines Corp.
  33. * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  34. * (c) Copyright 1993, 1994 Novell, Inc.
  35. */
  36. /*
  37. * Included Files:
  38. */
  39. #include "WmGlobal.h"
  40. #include <stdio.h>
  41. #include <X11/Xos.h>
  42. #include "WmICCC.h"
  43. #include "WmWrkspace.h" /* for ClientInWorkspace() test */
  44. #include <Dt/EnvControlP.h> /* for restoring **environ before an exec() */
  45. #include "WmResNames.h"
  46. #include <Dt/Message.h>
  47. #include <Dt/Help.h>
  48. #include <Dt/DtStrDefs.h>
  49. #include "WmPanelP.h"
  50. #include "WmSignal.h"
  51. #include "WmManage.h"
  52. /*
  53. * include extern functions
  54. */
  55. #include "WmFunction.h"
  56. #include "WmCEvent.h"
  57. #include "WmHelp.h"
  58. #include "WmCDInfo.h"
  59. #include "WmColormap.h"
  60. #include "WmError.h"
  61. #include "WmEvent.h"
  62. #include "WmFeedback.h"
  63. #include "WmIPC.h"
  64. #include "WmIPlace.h"
  65. #include "WmIconBox.h"
  66. #include "WmInstantTitle.h"
  67. #include "WmKeyFocus.h"
  68. #include "WmMenu.h"
  69. #include "WmPresence.h"
  70. #include "WmProperty.h"
  71. #include "WmProtocol.h"
  72. #include "WmResParse.h"
  73. #include "WmWinConf.h"
  74. #include "WmWinInfo.h"
  75. #include "WmWinList.h"
  76. #include "WmWinState.h"
  77. #include "WmXSMP.h"
  78. #include <Xm/RowColumnP.h> /* for MS_LastManagedMenuTime */
  79. extern XmMenuState _XmGetMenuState();
  80. #if defined(HAVE_CONFIG_H)
  81. #include <cde_config.h>
  82. #endif
  83. #if defined(HAVE_SYS_TYPES_H)
  84. #include <sys/types.h>
  85. #endif
  86. #include <unistd.h>
  87. #include <stdlib.h>
  88. #if defined(HAVE_VFORK) && defined(HAVE_VFORK_H)
  89. #include <vfork.h>
  90. #endif
  91. static unsigned int GetEventInverseMask(XEvent *event);
  92. #if !defined(_NFILE)
  93. #define _NFILE FOPEN_MAX
  94. #endif
  95. #define CLOSE_FILES_ON_EXEC() \
  96. {int ifx; for (ifx=3; ifx < _NFILE; ifx++) (void) fcntl (ifx, F_SETFD, FD_CLOEXEC);}
  97. /*
  98. * Global Variables:
  99. */
  100. /*
  101. * The 'dirty' variables are used to keep track of the transient window
  102. * that has been lowered via "f.lower freeFamily".
  103. */
  104. static ClientData *dirtyStackEntry = NULL;
  105. static ClientData *dirtyLeader = NULL;
  106. /***********************<->*************************************
  107. *
  108. * F_Action (args, pCD, event)
  109. *
  110. *
  111. * Description:
  112. * -----------
  113. * This is the window manager function handler for invoking actions.
  114. *
  115. *
  116. * Inputs:
  117. * ------
  118. * args = action function and arguments
  119. *
  120. * pCD = pointer to the ClientData for the whole front panel
  121. *
  122. * event = X event that invoked the function (key, button, or menu/NULL)
  123. *
  124. *
  125. * Outputs:
  126. * -------
  127. * RETURN = if True then further button binding/function processing can
  128. * be done for the event that caused this function to be called.
  129. *
  130. * Comments:
  131. * -------
  132. * The pCD->controlWindow is a temporary area used solely for
  133. * this function invocation--it stores the pCW of the control
  134. * that want the function to happen.
  135. ******************************<->***********************************/
  136. Boolean
  137. F_Action (String actionName, ClientData *pCD, XEvent *event)
  138. {
  139. WmActionArg *pAP = (WmActionArg *) actionName;
  140. /* make sure the command runs on the right display. */
  141. if (wmGD.pActiveSD->displayString)
  142. {
  143. putenv(wmGD.pActiveSD->displayString);
  144. }
  145. if (wmGD.dtSD)
  146. {
  147. WmFrontPanelSetBusy (True);
  148. }
  149. DtActionInvoke (wmGD.pActiveSD->screenTopLevelW1,
  150. pAP->actionName, pAP->aap, pAP->numArgs,
  151. pAP->szExecParms, NULL, NULL, 1, NULL, NULL);
  152. /*
  153. * Restore original DISPLAY environment variable
  154. */
  155. if(wmGD.pActiveSD->displayString && wmGD.displayString)
  156. {
  157. putenv(wmGD.displayString);
  158. }
  159. return (True);
  160. } /* END OF FUNCTION F_Action */
  161. /******************************<->*************************************
  162. *
  163. * F_Beep (args, pCD, event)
  164. *
  165. *
  166. * Description:
  167. * -----------
  168. * This is the window manager function handler for beeping.
  169. *
  170. *
  171. * Inputs:
  172. * ------
  173. * args = function arguments (specified in .mwmrc file)
  174. *
  175. * pCD = pointer to the client data for the client window to which the
  176. * function is to be applied
  177. *
  178. * event = X event that invoked the function (key, button, or menu/NULL)
  179. *
  180. *
  181. * Outputs:
  182. * -------
  183. * RETURN = if True then further button binding/function processing can
  184. * be done for the event that caused this function to be called.
  185. *
  186. ******************************<->***********************************/
  187. Boolean F_Beep (String args, ClientData *pCD, XEvent *event)
  188. {
  189. /* !!! what is a good value for percent (the second arg) !!! */
  190. XBell (DISPLAY, 0);
  191. return (True);
  192. } /* END OF FUNCTION F_Beep */
  193. /*
  194. * Handle Special case where the dirty window is the top most
  195. * transient window. When this is the case, raising the window
  196. * that was on top (the window just below the dirty window) will
  197. * fail because Mwm stack database is out of sync. So the solution
  198. * is to restack the dirty transient relative to the second to the
  199. * top transient. This function is used to support freeFamily stacking.
  200. */
  201. ClientData * FindSecondToTopTransient (ClientData *pcd)
  202. {
  203. ClientData *pcdNext;
  204. static ClientData *second;
  205. pcdNext = pcd->transientChildren;
  206. while (pcdNext)
  207. {
  208. if (pcdNext->transientChildren)
  209. {
  210. if (!pcdNext->transientChildren->transientChildren)
  211. {
  212. second = pcdNext;
  213. }
  214. FindSecondToTopTransient (pcdNext);
  215. }
  216. pcdNext = pcdNext->transientSiblings;
  217. if (pcdNext && !pcdNext->transientSiblings)
  218. {
  219. second = pcdNext;
  220. }
  221. }
  222. return (second);
  223. } /* END OF FUNCTION */
  224. Boolean ForceLowerWindow (ClientData *pcd)
  225. {
  226. #if 0
  227. Window stackWindow;
  228. WmScreenData *pSD = (ACTIVE_WS)->pSD;
  229. #endif
  230. XWindowChanges changes;
  231. Boolean restack = False;
  232. Window stackWindow;
  233. WmScreenData *pSD = (ACTIVE_WS)->pSD;
  234. unsigned int mask;
  235. ClientListEntry *pCLE;
  236. /*
  237. * Find lowest window in this workspace. We'll stack this transient
  238. * below it.
  239. */
  240. pCLE = pSD->lastClient;
  241. stackWindow = None;
  242. mask = CWStackMode;
  243. while (pCLE != NULL)
  244. {
  245. if ((pCLE->pCD != pcd) &&
  246. (ClientInWorkspace (ACTIVE_WS, pCLE->pCD)))
  247. {
  248. if ((pCLE->type == MINIMIZED_STATE) &&
  249. (pCLE->pCD->clientState == MINIMIZED_STATE))
  250. {
  251. stackWindow = ICON_FRAME_WIN(pCLE->pCD);
  252. }
  253. else if ((pCLE->type == NORMAL_STATE) &&
  254. ((pCLE->pCD->clientState == NORMAL_STATE) ||
  255. (pCLE->pCD->clientState == MAXIMIZED_STATE)))
  256. {
  257. stackWindow = pCLE->pCD->clientFrameWin;
  258. }
  259. if (stackWindow != None)
  260. {
  261. mask |= CWSibling;
  262. changes.sibling = stackWindow;
  263. break;
  264. }
  265. }
  266. if (stackWindow == None)
  267. {
  268. pCLE = pCLE->prevSibling;
  269. }
  270. }
  271. #if 0
  272. if (pSD->lastClient->type == MINIMIZED_STATE)
  273. {
  274. stackWindow = ICON_FRAME_WIN(pSD->lastClient->pCD);
  275. }
  276. else
  277. {
  278. stackWindow = pSD->lastClient->pCD->clientFrameWin;
  279. }
  280. #endif
  281. changes.stack_mode = Below;
  282. if (mask)
  283. {
  284. XConfigureWindow (DISPLAY, pcd->clientFrameWin, mask, &changes);
  285. }
  286. return (restack);
  287. }
  288. /*************************************<->*************************************
  289. *
  290. * F_Lower (args, pCD, event)
  291. *
  292. *
  293. * Description:
  294. * -----------
  295. * This is the window manager function handler for bottoming a client window
  296. * or icon.
  297. *
  298. *
  299. * Inputs:
  300. * ------
  301. * args = function arguments (specified in .mwmrc file)
  302. *
  303. * pCD = pointer to the client data for the client window to which the
  304. * function is to be applied
  305. *
  306. * event = X event that invoked the function (key, button, or menu/NULL)
  307. *
  308. *
  309. * Outputs:
  310. * -------
  311. * RETURN = if True then further button binding/function processing can
  312. * be done for the event that caused this function to be called.
  313. *
  314. *************************************<->***********************************/
  315. Boolean F_Lower (String args, ClientData *pCD, XEvent *event)
  316. {
  317. ClientListEntry *pEntry;
  318. ClientListEntry *pNextEntry;
  319. ClientListEntry *pStackEntry;
  320. String string = args;
  321. int flags = STACK_NORMAL;
  322. WmWorkspaceData *pWS = ACTIVE_WS;
  323. if (string)
  324. {
  325. /* process '-client' argument */
  326. if (string[0] == '-')
  327. {
  328. string = &string[1];
  329. string = (String) GetString ((unsigned char **) &string);
  330. pStackEntry = NULL;
  331. pNextEntry = ACTIVE_PSD->lastClient;
  332. while (pNextEntry &&
  333. (pEntry = FindClientNameMatch (pNextEntry, False,
  334. string, F_GROUP_ALL)))
  335. {
  336. pNextEntry = pEntry->prevSibling;
  337. if (ClientInWorkspace (pWS, pEntry->pCD))
  338. {
  339. Do_Lower (pEntry->pCD, pStackEntry, STACK_NORMAL);
  340. pStackEntry = pEntry;
  341. }
  342. }
  343. }
  344. /* process family stacking stuff */
  345. else if (*string)
  346. {
  347. unsigned int slen, len, index;
  348. slen = strlen(args) - 2; /* subtract '\n' and NULL */
  349. for (index = 0; index < slen; string = &args[index+1])
  350. {
  351. if ((string = (String) GetString ((unsigned char **) &string)) == NULL)
  352. break;
  353. len = strlen(string);
  354. if (!strcmp(string,"within"))
  355. {
  356. flags |= STACK_WITHIN_FAMILY;
  357. }
  358. else if (!strcmp(string,"freeFamily"))
  359. {
  360. flags |= STACK_FREE_FAMILY;
  361. }
  362. index += len;
  363. }
  364. if (ClientInWorkspace (pWS, pCD))
  365. {
  366. Do_Lower (pCD, (ClientListEntry *) NULL, flags);
  367. }
  368. }
  369. }
  370. else if (pCD)
  371. {
  372. if (ClientInWorkspace (pWS, pCD))
  373. {
  374. Do_Lower (pCD, (ClientListEntry *) NULL, STACK_NORMAL);
  375. }
  376. }
  377. /*
  378. * If caused by button press, event may ALSO cause focus to be
  379. * passed to this client - prepare to disable focusAutoRaise.
  380. */
  381. if (pCD && event && (event->type == ButtonPress))
  382. pCD->focusAutoRaiseDisablePending = True;
  383. wmGD.passButtonsCheck = False;
  384. return (True);
  385. } /* END OF FUNCTION F_Lower */
  386. /*************************************<->*************************************
  387. *
  388. * Do_Lower (pCD, pStackEntry)
  389. *
  390. *
  391. * Description:
  392. * -----------
  393. * This is the window manager function handler for lowering the client window
  394. * so that it does not obscure any other window above the stack entry
  395. * window.
  396. *
  397. *
  398. * Inputs:
  399. * ------
  400. * pCD = pointer to the client data of the window (or icon) to be lowered.
  401. *
  402. * pStackEntry = pointer to client list entry for window that is to be
  403. * below the lowered window (if NULL, window is lowered to the bottom
  404. * of the stack).
  405. *
  406. *************************************<->***********************************/
  407. void Do_Lower (ClientData *pCD, ClientListEntry *pStackEntry, int flags)
  408. {
  409. Boolean restackTransients;
  410. ClientData *pcdLeader;
  411. WmWorkspaceData *pWS = ACTIVE_WS;
  412. Boolean bLeaderRestacked;
  413. if (pCD->pECD)
  414. {
  415. /*
  416. * Window has been reparented into the front panel.
  417. * Don't follow through on window stacking change.
  418. */
  419. return;
  420. }
  421. else
  422. if (ClientInWorkspace(pWS, pCD) &&
  423. (!pStackEntry || ClientInWorkspace (pWS, pStackEntry->pCD)))
  424. {
  425. /*
  426. * Both clients are in the current workspace. Set
  427. * client indices so that the access macros work.
  428. */
  429. SetClientWsIndex (pCD);
  430. if (pStackEntry)
  431. {
  432. SetClientWsIndex (pStackEntry->pCD);
  433. }
  434. }
  435. else
  436. {
  437. /*
  438. * One or both of the clients are not in the current workspace
  439. * Do nothing.
  440. */
  441. return;
  442. }
  443. pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
  444. if ((pcdLeader->clientState == MINIMIZED_STATE) && !P_ICON_BOX(pcdLeader))
  445. {
  446. /*
  447. * If a dirtyStackEntry exists, return it to its original place
  448. * in the stack (for all stacking types)
  449. */
  450. if (dirtyStackEntry)
  451. {
  452. if (dirtyStackEntry->transientChildren ||
  453. dirtyStackEntry->transientLeader)
  454. RestackTransients (dirtyStackEntry);
  455. dirtyStackEntry = NULL;
  456. dirtyLeader = NULL;
  457. }
  458. /*
  459. * Only restack the icon if it is not currently lowered.
  460. */
  461. if (pStackEntry)
  462. {
  463. if (pStackEntry->prevSibling != &pcdLeader->iconEntry)
  464. {
  465. StackWindow (pWS, &pcdLeader->iconEntry, True /*above*/,
  466. pStackEntry);
  467. MoveEntryInList (pWS, &pcdLeader->iconEntry, True /*above*/,
  468. pStackEntry);
  469. }
  470. }
  471. else
  472. {
  473. if (ACTIVE_PSD->lastClient != &pcdLeader->iconEntry)
  474. {
  475. StackWindow (pWS, &pcdLeader->iconEntry,
  476. False /*on bottom*/, (ClientListEntry *) NULL);
  477. MoveEntryInList (pWS, &pcdLeader->iconEntry,
  478. False /*on bottom*/, (ClientListEntry *) NULL);
  479. }
  480. }
  481. }
  482. else /* NORMAL_STATE, MAXIMIZED_STATE, adoption */
  483. {
  484. /*
  485. * Handle restacking of primary/secondary windows
  486. * within the transient window tree.
  487. */
  488. bLeaderRestacked = False;
  489. if ((pcdLeader->transientChildren) &&
  490. (!pcdLeader->secondariesOnTop) &&
  491. (!wmGD.bSuspendSecondaryRestack))
  492. {
  493. if (pCD == pcdLeader)
  494. {
  495. /*
  496. * Lower requested on the leader itself, insure it's
  497. * at the bottom.
  498. */
  499. bLeaderRestacked = BumpPrimaryToBottom (pcdLeader);
  500. }
  501. else if (pCD->transientChildren)
  502. {
  503. /*
  504. * Lower requested on the leader of a subtree. Insure
  505. * that this subtree leader is at the bottom of the
  506. * subtree.
  507. */
  508. bLeaderRestacked = BumpPrimaryToBottom (pCD);
  509. }
  510. else if (pCD->transientLeader)
  511. {
  512. ClientData *pcdLdr;
  513. /*
  514. * Lower requested on a transient. Insure all the
  515. * subtree leaders up to the top are at the bottom
  516. * of their respective transient subtrees.
  517. */
  518. for (pcdLdr = pCD->transientLeader;
  519. pcdLdr;
  520. pcdLdr = pcdLdr->transientLeader)
  521. {
  522. bLeaderRestacked |= BumpPrimaryToBottom (pcdLdr);
  523. }
  524. }
  525. }
  526. /*
  527. * If this is a transient window then put it below its
  528. * sibling transient windows.
  529. */
  530. restackTransients = False;
  531. if (pCD->transientLeader)
  532. {
  533. /*
  534. * If freeFamily stacking, then put dirty transient window
  535. * (if any) back in place before force lowering current window
  536. * to the bottom of the global window stack. Then return.
  537. */
  538. if (flags & STACK_FREE_FAMILY)
  539. {
  540. /* Restore dirty transient if not current window. */
  541. if ((dirtyStackEntry) &&
  542. (dirtyStackEntry != pCD))
  543. {
  544. RestackTransients (dirtyStackEntry);
  545. }
  546. dirtyStackEntry = pCD;
  547. dirtyLeader = pcdLeader;
  548. ForceLowerWindow (pCD);
  549. return;
  550. }
  551. /*
  552. * Reach here only if NOT doing a f.lower freeFamily (see
  553. * return; statement above). Put current transient below
  554. * its sibling transient windows.
  555. */
  556. restackTransients = PutTransientBelowSiblings (pCD);
  557. }
  558. /*
  559. * If doing a regular f.lower and you have a dirty window, then
  560. * clean up dirty transient window.
  561. */
  562. if (dirtyStackEntry)
  563. {
  564. /*
  565. * If lowering a window in the same family as the dirty
  566. * transient window, then just restack before lowering.
  567. * Else, restore the dirty transient in place before
  568. * lowering the current window. Clear dirtyStack.
  569. */
  570. if (dirtyLeader == pcdLeader)
  571. {
  572. restackTransients = True;
  573. }
  574. else
  575. {
  576. RestackTransients (dirtyStackEntry);
  577. }
  578. dirtyStackEntry = NULL;
  579. }
  580. /*
  581. * Only restack the window or transient window tree if it is
  582. * not currently lowered and the window is not a system
  583. * modal window.
  584. */
  585. if (pStackEntry)
  586. {
  587. if ((pStackEntry->prevSibling != &pcdLeader->clientEntry) &&
  588. !(wmGD.systemModalActive &&
  589. (pcdLeader == wmGD.systemModalClient)))
  590. {
  591. StackWindow (pWS, &pcdLeader->clientEntry, True /*above*/,
  592. pStackEntry);
  593. MoveEntryInList (pWS, &pcdLeader->clientEntry, True /*above*/,
  594. pStackEntry);
  595. }
  596. else if ((restackTransients) || (bLeaderRestacked))
  597. {
  598. RestackTransients (pCD);
  599. }
  600. }
  601. else
  602. {
  603. if ((pWS->pSD->lastClient != &pcdLeader->clientEntry) &&
  604. !(wmGD.systemModalActive &&
  605. (pcdLeader == wmGD.systemModalClient)) &&
  606. !(flags & STACK_WITHIN_FAMILY))
  607. {
  608. StackWindow (pWS, &pcdLeader->clientEntry, False /*on bottom*/,
  609. (ClientListEntry *) NULL);
  610. MoveEntryInList (pWS, &pcdLeader->clientEntry,
  611. False /*on bottom*/, (ClientListEntry *) NULL);
  612. }
  613. else if ((restackTransients) || (bLeaderRestacked))
  614. {
  615. RestackTransients (pCD);
  616. }
  617. }
  618. }
  619. } /* END OF FUNCTION Do_Lower */
  620. /*************************************<->*************************************
  621. *
  622. * F_CircleDown (args, pCD, event)
  623. *
  624. *
  625. * Description:
  626. * -----------
  627. * This is the window manager function handler for moving the client window
  628. * on top of stack to the bottom.
  629. *
  630. *
  631. * Inputs:
  632. * ------
  633. * args = function arguments (specified in .mwmrc file)
  634. *
  635. * pCD = pointer to the client data for the client window to which the
  636. * function is to be applied
  637. *
  638. * event = X event that invoked the function (key, button, or menu/NULL)
  639. *
  640. *
  641. * Outputs:
  642. * -------
  643. * RETURN = if True then further button binding/function processing can
  644. * be done for the event that caused this function to be called.
  645. *
  646. *************************************<->***********************************/
  647. Boolean F_Circle_Down (String args, ClientData *pCD, XEvent *event)
  648. {
  649. unsigned long types;
  650. unsigned long windowType;
  651. ClientListEntry *pNextEntry;
  652. ClientData *pcdNext;
  653. /*
  654. * Go down through the client list looking for a window of an
  655. * appropriate type that is obscuring lower windows.
  656. */
  657. types = (unsigned long)args;
  658. pNextEntry = ACTIVE_PSD->clientList;
  659. while (pNextEntry)
  660. {
  661. /*
  662. * Only check out the window if it is onscreen.
  663. */
  664. pcdNext = pNextEntry->pCD;
  665. if (((pNextEntry->type == NORMAL_STATE) &&
  666. (pcdNext->clientState != MINIMIZED_STATE)) ||
  667. ((pNextEntry->type == MINIMIZED_STATE) &&
  668. (pcdNext->clientState == MINIMIZED_STATE)))
  669. {
  670. if (pcdNext->clientState == MINIMIZED_STATE)
  671. {
  672. windowType = F_GROUP_ICON;
  673. }
  674. else
  675. {
  676. windowType = F_GROUP_WINDOW;
  677. if (pcdNext->transientLeader || pcdNext->transientChildren)
  678. {
  679. windowType |= F_GROUP_TRANSIENT;
  680. }
  681. }
  682. if (types & windowType)
  683. {
  684. if (CheckIfClientObscuringAny (pcdNext))
  685. {
  686. /*
  687. * This window (or window tree) is obscuring another window
  688. * on the screen. Lower the window.
  689. */
  690. wmGD.bSuspendSecondaryRestack = True;
  691. F_Lower (NULL, pcdNext, (XEvent *) NULL);
  692. wmGD.bSuspendSecondaryRestack = False;
  693. break;
  694. }
  695. }
  696. }
  697. pNextEntry = pNextEntry->nextSibling;
  698. }
  699. return (True);
  700. } /* END OF FUNCTION F_Circle_Down */
  701. /*************************************<->*************************************
  702. *
  703. * F_Circle_Up (args, pCD, event)
  704. *
  705. *
  706. * Description:
  707. * -----------
  708. * This is the window manager function handler for moving the client window
  709. * on the bottom of the stack to the top.
  710. *
  711. *
  712. * Inputs:
  713. * ------
  714. * args = function arguments (specified in .mwmrc file)
  715. *
  716. * pCD = pointer to the client data for the client window to which the
  717. * function is to be applied
  718. *
  719. * event = X event that invoked the function (key, button, or menu/NULL)
  720. *
  721. *
  722. * Outputs:
  723. * -------
  724. * RETURN = if True then further button binding/function processing can
  725. * be done for the event that caused this function to be called.
  726. *
  727. *************************************<->***********************************/
  728. Boolean F_Circle_Up (String args, ClientData *pCD, XEvent *event)
  729. {
  730. unsigned long types;
  731. unsigned long windowType;
  732. ClientListEntry *pNextEntry;
  733. ClientData *pcdNext;
  734. /*
  735. * Go up through the client list looking for a window of an
  736. * appropriate type that is obscured by higher windows.
  737. */
  738. types = (unsigned long)args;
  739. pNextEntry = ACTIVE_PSD->lastClient;
  740. while (pNextEntry)
  741. {
  742. /*
  743. * Only check out the window if it is onscreen.
  744. */
  745. pcdNext = pNextEntry->pCD;
  746. if (((pNextEntry->type == NORMAL_STATE) &&
  747. (pcdNext->clientState != MINIMIZED_STATE)) ||
  748. ((pNextEntry->type == MINIMIZED_STATE) &&
  749. (pcdNext->clientState == MINIMIZED_STATE)))
  750. {
  751. if (pcdNext->clientState == MINIMIZED_STATE)
  752. {
  753. windowType = F_GROUP_ICON;
  754. }
  755. else
  756. {
  757. windowType = F_GROUP_WINDOW;
  758. if (pcdNext->transientLeader || pcdNext->transientChildren)
  759. {
  760. windowType |= F_GROUP_TRANSIENT;
  761. }
  762. }
  763. if (types & windowType)
  764. {
  765. if (CheckIfClientObscuredByAny (pcdNext))
  766. {
  767. /*
  768. * This window (or window tree) is obscured by another
  769. * window on the screen. Raise the window.
  770. */
  771. wmGD.bSuspendSecondaryRestack = True;
  772. F_Raise (NULL, pcdNext, (XEvent *) NULL);
  773. wmGD.bSuspendSecondaryRestack = False;
  774. break;
  775. }
  776. }
  777. }
  778. pNextEntry = pNextEntry->prevSibling;
  779. }
  780. return (True);
  781. } /* END OF FUNCTION F_Circle_Up */
  782. /*************************************<->*************************************
  783. *
  784. * F_Focus_Color (args, pCD, event)
  785. *
  786. *
  787. * Description:
  788. * -----------
  789. * This is the window manager function handler for setting the colormap
  790. * focus to a client window or reinstalling the default colormap.
  791. *
  792. *************************************<->***********************************/
  793. Boolean F_Focus_Color (String args, ClientData *pCD, XEvent *event)
  794. {
  795. if (wmGD.colormapFocusPolicy == CMAP_FOCUS_EXPLICIT)
  796. {
  797. if (pCD)
  798. {
  799. /*
  800. * The window selected for the colormap focus is a top-level client
  801. * window. If there are subwindow colormaps then determine if the
  802. * selection was in one of the subwindows.
  803. */
  804. if (pCD->clientState == MINIMIZED_STATE)
  805. {
  806. /* !!! colormap for client supplied icon window !!! */
  807. pCD = NULL;
  808. }
  809. }
  810. SetColormapFocus (ACTIVE_PSD, pCD);
  811. }
  812. return (True);
  813. } /* END OF FUNCTION F_Focus_Color */
  814. /*************************************<->*************************************
  815. *
  816. * F_Exec (args, pCD, event)
  817. *
  818. *
  819. * Description:
  820. * -----------
  821. * This is the window manager function handler for executing a command
  822. * (with /bin/sh).
  823. *
  824. *************************************<->***********************************/
  825. Boolean F_Exec (String args, ClientData *pCD, XEvent *event)
  826. {
  827. int pid;
  828. char *shell;
  829. char *shellname;
  830. /* make sure the f.exec command runs on the right display. */
  831. if (wmGD.pActiveSD->displayString)
  832. {
  833. putenv(wmGD.pActiveSD->displayString);
  834. }
  835. if (wmGD.dtSD)
  836. {
  837. /*
  838. * Start the busy indicator, waiting for a pushbutton window
  839. * for the given duration
  840. */
  841. WmFrontPanelSetBusy (True);
  842. }
  843. /*
  844. * Fork a process to exec a shell to run the specified command:
  845. */
  846. #if defined(HAVE_VFORK)
  847. if ((pid = vfork ()) == 0)
  848. #else
  849. if ((pid = fork ()) == 0)
  850. #endif
  851. {
  852. #if defined(SVR4) || defined(__linux__)
  853. setsid();
  854. #else
  855. #ifdef SYSV
  856. setpgrp();
  857. #else
  858. int tpid;
  859. tpid = getpid();
  860. setpgrp(tpid, tpid);
  861. #endif /* SYSV */
  862. #endif /* SVR4 */
  863. /*
  864. * Clean up window manager resources.
  865. * The X file descriptor should be automatically closed.
  866. */
  867. /*
  868. * Fix up signal handling.
  869. */
  870. RestoreDefaultSignalHandlers ();
  871. /*
  872. * Fix up the child application's environment NOT to
  873. * inherit the XFILESEARCHPATH, XBMLANGPATH, NLSPATH, etc.
  874. * used by dtwm.
  875. */
  876. _DtEnvControl(DT_ENV_RESTORE_PRE_DT);
  877. CLOSE_FILES_ON_EXEC();
  878. /*
  879. * Exec the command using $MWMSHELL if set or
  880. * $SHELL if set and $MWMSHELL not set or sh.
  881. */
  882. if (((shell = getenv ("MWMSHELL")) != NULL) ||
  883. ((shell = getenv ("SHELL")) != NULL))
  884. {
  885. shellname = strrchr (shell, '/');
  886. if (shellname == NULL)
  887. {
  888. /*
  889. If the shell pathname obtained from SHELL or MWMSHELL does not
  890. have a "/" in the path and if the user expects this shell to be
  891. obtained using the PATH variable rather than the current
  892. directory, then we must call execlp and not execl
  893. */
  894. shellname = shell;
  895. execlp (shell, shellname, "-c", args, NULL);
  896. }
  897. else
  898. {
  899. shellname++;
  900. execl (shell, shellname, "-c", args, NULL);
  901. }
  902. }
  903. /*
  904. * There is no SHELL environment variable or the first execl failed.
  905. * Try /bin/sh .
  906. */
  907. #ifdef SVR4
  908. execl ("/usr/bin/sh", "sh", "-c", args, NULL);
  909. #else
  910. execl ("/bin/sh", "sh", "-c", args, NULL);
  911. #endif
  912. /*
  913. * Error - command could not be exec'ed.
  914. */
  915. _exit (127);
  916. }
  917. else if (pid == -1)
  918. return(True);
  919. /*
  920. * Have the window manager wait for the shell to complete.
  921. */
  922. /*
  923. * Don't need to wait because WSM sets SIGCLD handler
  924. */
  925. /*
  926. * Restore original DISPLAY environment variable value
  927. * so a restart will start on the same screen
  928. */
  929. if(wmGD.pActiveSD->displayString &&
  930. wmGD.displayString)
  931. {
  932. putenv(wmGD.displayString);
  933. }
  934. return (True);
  935. } /* END OF FUNCTION F_Exec */
  936. /*************************************<->*************************************
  937. *
  938. * F_Quit_Mwm (args, pCD, event)
  939. *
  940. *
  941. * Description:
  942. * -----------
  943. * This is the window manager function handler for terminating the window
  944. * manager.
  945. *
  946. *************************************<->***********************************/
  947. Boolean F_Quit_Mwm (String args, ClientData *pCD, XEvent *event)
  948. {
  949. if (wmGD.showFeedback & WM_SHOW_FB_QUIT)
  950. {
  951. ConfirmAction (ACTIVE_PSD, QUIT_MWM_ACTION);
  952. }
  953. else
  954. {
  955. Do_Quit_Mwm(False);
  956. }
  957. return (False);
  958. } /* END OF FUNCTION F_Quit_Mwm */
  959. /*************************************<->*************************************
  960. *
  961. * Do_Quit_Mwm (diedOnRestart)
  962. *
  963. *
  964. * Description:
  965. * -----------
  966. * Callback to do the f.quit_mwm function.
  967. *
  968. *************************************<->***********************************/
  969. void Do_Quit_Mwm (Boolean diedOnRestart)
  970. {
  971. int scr;
  972. ClientListEntry *pNextEntry;
  973. /*
  974. * Close the X connection to get all the X resources cleaned up.
  975. * !!! maybe windows should be reparented / rebordered before closing? !!!
  976. * !!! clean up the _MOTIF_WM_INFO property on the root window !!!
  977. */
  978. if (DISPLAY)
  979. {
  980. XSetInputFocus(DISPLAY, PointerRoot, RevertToPointerRoot, CurrentTime);
  981. for (scr = 0; scr < wmGD.numScreens; scr++)
  982. {
  983. if (wmGD.Screens[scr].managed)
  984. {
  985. SaveResources(&wmGD.Screens[scr]);
  986. pNextEntry = wmGD.Screens[scr].lastClient;
  987. while (pNextEntry)
  988. {
  989. if (pNextEntry->type == NORMAL_STATE)
  990. {
  991. if (!(pNextEntry->pCD->clientFlags &
  992. CLIENT_WM_CLIENTS))
  993. {
  994. ReBorderClient (pNextEntry->pCD, diedOnRestart);
  995. }
  996. }
  997. pNextEntry = pNextEntry->prevSibling;
  998. }
  999. UnParentControls (&wmGD.Screens[scr], False);
  1000. }
  1001. }
  1002. /* shut down the messaging connection */
  1003. dtCloseIPC();
  1004. ResignFromSM();
  1005. XSync (DISPLAY, False);
  1006. XCloseDisplay (DISPLAY);
  1007. }
  1008. if(diedOnRestart)
  1009. {
  1010. exit (WM_ERROR_EXIT_VALUE);
  1011. }
  1012. else
  1013. {
  1014. exit (0);
  1015. }
  1016. } /* END OF FUNCTION Do_Quit_Mwm */
  1017. /*************************************<->*************************************
  1018. *
  1019. * ReBorderClient (pCD, reMapClient)
  1020. *
  1021. *
  1022. * Description:
  1023. * -----------
  1024. * Restores X border for client window and reparents the
  1025. * window back to the root.
  1026. *
  1027. *
  1028. * Inputs:
  1029. * -------
  1030. * pCD = pointer to the client data for the window to be re-bordered.
  1031. *
  1032. *************************************<->***********************************/
  1033. void ReBorderClient (ClientData *pCD, Boolean reMapClient)
  1034. {
  1035. int x, y;
  1036. int xoff, yoff;
  1037. XWindowChanges windowChanges;
  1038. while (pCD)
  1039. {
  1040. if (pCD->iconWindow && (pCD->clientFlags & ICON_REPARENTED) &&
  1041. (!(reMapClient)))
  1042. {
  1043. XUnmapWindow (DISPLAY, pCD->iconWindow);
  1044. XReparentWindow (DISPLAY, pCD->iconWindow,
  1045. ROOT_FOR_CLIENT(pCD), pCD->pWsList->iconX,
  1046. pCD->pWsList->iconY);
  1047. }
  1048. if (!(reMapClient))
  1049. {
  1050. if (pCD->maxConfig)
  1051. {
  1052. x = pCD->maxX;
  1053. y = pCD->maxY;
  1054. }
  1055. else
  1056. {
  1057. if(wmGD.positionIsFrame)
  1058. {
  1059. CalculateGravityOffset (pCD, &xoff, &yoff);
  1060. x = pCD->clientX - xoff;
  1061. y = pCD->clientY - yoff;
  1062. }
  1063. else
  1064. {
  1065. x = pCD->clientX;
  1066. y = pCD->clientY;
  1067. }
  1068. }
  1069. XUnmapWindow(DISPLAY, pCD->clientFrameWin);
  1070. XReparentWindow (DISPLAY, pCD->client,
  1071. ROOT_FOR_CLIENT(pCD), x, y);
  1072. }
  1073. else
  1074. {
  1075. XMapWindow(wmGD.display, pCD->client);
  1076. }
  1077. if (pCD->transientChildren)
  1078. {
  1079. ReBorderClient (pCD->transientChildren, reMapClient);
  1080. }
  1081. if (!(reMapClient))
  1082. {
  1083. /*
  1084. * restore X border
  1085. */
  1086. windowChanges.x = x;
  1087. windowChanges.y = y;
  1088. windowChanges.border_width = pCD->xBorderWidth;
  1089. XConfigureWindow (DISPLAY, pCD->client,
  1090. CWBorderWidth | CWX | CWY, &windowChanges);
  1091. }
  1092. if (pCD->transientLeader)
  1093. {
  1094. pCD = pCD->transientSiblings;
  1095. }
  1096. else
  1097. {
  1098. pCD = NULL;
  1099. }
  1100. }
  1101. } /* END OF FUNCTION ReBorderClient */
  1102. /*************************************<->*************************************
  1103. *
  1104. * F_Focus_Key (args, pCD, event)
  1105. *
  1106. *
  1107. * Description:
  1108. * -----------
  1109. * This is the window manager function handler for setting the keyboard
  1110. * focus to a particular client window.
  1111. *
  1112. *
  1113. * Inputs:
  1114. * ------
  1115. * args = (immediate value) focus flags
  1116. *
  1117. * pCD = pointer to the client data
  1118. *
  1119. * event = X event that invoked the function (key, button, or menu/NULL)
  1120. *
  1121. *************************************<->***********************************/
  1122. Boolean F_Focus_Key (String args, ClientData *pCD, XEvent *event)
  1123. {
  1124. long focusFlags = (long)args;
  1125. if (pCD && (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
  1126. {
  1127. Do_Focus_Key (pCD, GetFunctionTimestamp ((XButtonEvent *)event),
  1128. (focusFlags | ALWAYS_SET_FOCUS));
  1129. }
  1130. return (True);
  1131. } /* END OF FUNCTION F_Focus_Key */
  1132. /*************************************<->*************************************
  1133. *
  1134. * FindSomeReasonableClient
  1135. *
  1136. * Description:
  1137. * -----------
  1138. * Find a client, any client to set the focus to, return client or NULL.
  1139. * This code is ripped off from AutoResetKeyFocus().
  1140. *
  1141. *************************************<->***********************************/
  1142. static Window FindSomeReasonableClient(void)
  1143. {
  1144. ClientData *pcdNoFocus=NULL;
  1145. ClientListEntry *pNextEntry;
  1146. ClientData *pCD;
  1147. ClientData *pcdLastFocus = (ClientData *) NULL;
  1148. ClientData *pcdFocus;
  1149. Window focusWindow = (Window) NULL;
  1150. /*
  1151. * Scan through the list of clients to find a window to get the focus.
  1152. */
  1153. pNextEntry = ACTIVE_PSD->clientList;
  1154. while (pNextEntry)
  1155. {
  1156. pCD = pNextEntry->pCD;
  1157. if (!wmGD.systemModalActive ||
  1158. (wmGD.systemModalClient == pCD))
  1159. {
  1160. if ((pNextEntry->type != MINIMIZED_STATE) &&
  1161. (pCD->clientState != MINIMIZED_STATE) &&
  1162. (ClientInWorkspace (ACTIVE_WS, pCD)) &&
  1163. (pCD != pcdNoFocus))
  1164. {
  1165. if (pCD->transientChildren)
  1166. {
  1167. pcdFocus = FindLastTransientTreeFocus (pCD, pcdNoFocus);
  1168. }
  1169. else
  1170. {
  1171. pcdFocus = pCD;
  1172. }
  1173. if (pcdFocus &&
  1174. ((pcdLastFocus == NULL) ||
  1175. (pcdFocus->focusPriority > pcdLastFocus->focusPriority)))
  1176. {
  1177. pcdLastFocus = pcdFocus;
  1178. }
  1179. }
  1180. }
  1181. pNextEntry = pNextEntry->nextSibling;
  1182. }
  1183. /*
  1184. * Set the focus window if one is found
  1185. */
  1186. if (pcdLastFocus &&
  1187. ClientInWorkspace (ACTIVE_WS, pcdLastFocus))
  1188. focusWindow = pcdLastFocus->client;
  1189. /*
  1190. * If a client window could not be found, then just put focus
  1191. * on any icon.
  1192. */
  1193. if (focusWindow == (Window) NULL)
  1194. {
  1195. pNextEntry = ACTIVE_PSD->clientList;
  1196. while (pNextEntry)
  1197. {
  1198. pCD = pNextEntry->pCD;
  1199. if (ClientInWorkspace (ACTIVE_WS, pCD))
  1200. {
  1201. if ((pNextEntry->type == MINIMIZED_STATE) ||
  1202. (pCD->clientState == MINIMIZED_STATE))
  1203. {
  1204. focusWindow = ICON_FRAME_WIN(pCD);
  1205. break;
  1206. }
  1207. }
  1208. pNextEntry = pNextEntry->nextSibling;
  1209. }
  1210. }
  1211. return (focusWindow);
  1212. } /* END OF FUNCTION FindSomeReasonableClient */
  1213. /*************************************<->*************************************
  1214. *
  1215. * Do_Focus_Key (pCD, focusTime, flags)
  1216. *
  1217. *
  1218. * Description:
  1219. * -----------
  1220. * This function is used to set the focus to a window. The focus indication
  1221. * is not changed until the FocusIn event is received.
  1222. *
  1223. *
  1224. * Inputs:
  1225. * ------
  1226. * pCD = pointer to the client data
  1227. *
  1228. * focusTime = focus change time
  1229. *
  1230. * flags = wm focus change flags
  1231. *
  1232. *************************************<->***********************************/
  1233. void Do_Focus_Key (ClientData *pCD, Time focusTime, long flags)
  1234. {
  1235. ClientData *pcdFocus;
  1236. Window focusWindow;
  1237. /* Clear the replay flag */
  1238. wmGD.replayEnterEvent = False;
  1239. pcdFocus = pCD;
  1240. /*
  1241. * Make sure the client is in the current workspace
  1242. */
  1243. if ((pCD) &&
  1244. (ClientInWorkspace (ACTIVE_WS, pCD)))
  1245. {
  1246. if (pCD->clientState == MINIMIZED_STATE)
  1247. {
  1248. focusWindow = ICON_FRAME_WIN(pCD);
  1249. }
  1250. else if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT)
  1251. {
  1252. /*
  1253. * Set the keyboard focus to the indicated client window.
  1254. * If the window has an application modal subordinate then
  1255. * set the input focus to that window if the focus isn't
  1256. * already owned by a subordinate.
  1257. */
  1258. if (IS_APP_MODALIZED(pCD))
  1259. {
  1260. ClientData *pcdFocusLeader,*currFocusLeader;
  1261. /*
  1262. * Handle case where a modal window exists when Mwm starts up.
  1263. * wmGD.keyboardFocus is NULL, give focus to the modal dialog.
  1264. */
  1265. if (wmGD.keyboardFocus)
  1266. {
  1267. currFocusLeader = wmGD.keyboardFocus->transientLeader;
  1268. }
  1269. else
  1270. {
  1271. currFocusLeader = (ClientData *) NULL;
  1272. }
  1273. /*
  1274. * Find focus leader for pCD
  1275. */
  1276. pcdFocusLeader = pCD;
  1277. while (pcdFocusLeader->transientLeader &&
  1278. (pcdFocusLeader != currFocusLeader))
  1279. {
  1280. pcdFocusLeader = pcdFocusLeader->transientLeader;
  1281. }
  1282. if (pcdFocusLeader == currFocusLeader)
  1283. {
  1284. pcdFocus = wmGD.keyboardFocus;
  1285. flags = 0;
  1286. }
  1287. else
  1288. {
  1289. pcdFocus = FindTransientFocus (pcdFocusLeader);
  1290. }
  1291. }
  1292. /*
  1293. * !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
  1294. * We must look at why FindTransientFocus is
  1295. * returning a NULL pcd. The old code simply set
  1296. * focusWindow = pcdFocus->client;
  1297. * !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
  1298. *
  1299. * 11/26/96 rswiston - In tracking down CDExc22816, we
  1300. * discovered that pCD could get tricked into thinking
  1301. * it had modal transients when in fact all its transients
  1302. * had been withdrawn (fixed in WithdrawTransientChildren()).
  1303. * As a result, FindTransientFocus() returns wmGD.keyboardFocus;
  1304. * if nobody has the focus, FindTransientFocus() returns NULL.
  1305. */
  1306. if (pcdFocus)
  1307. {
  1308. focusWindow = pcdFocus->client;
  1309. }
  1310. else
  1311. {
  1312. focusWindow = (wmGD.keyboardFocus) ?
  1313. wmGD.keyboardFocus->client : ACTIVE_PSD->wmWorkspaceWin;
  1314. }
  1315. }
  1316. else
  1317. {
  1318. /*
  1319. * If the focus policy is "pointer" don't set the focus to a
  1320. * window if it has an application modal subordinate.
  1321. */
  1322. if (IS_APP_MODALIZED(pCD))
  1323. {
  1324. pcdFocus = NULL;
  1325. focusWindow = ACTIVE_PSD->wmWorkspaceWin;
  1326. /* Replay this later when the modal window is removed. */
  1327. wmGD.replayEnterEvent = True;
  1328. }
  1329. else
  1330. {
  1331. focusWindow = pcdFocus->client;
  1332. }
  1333. }
  1334. }
  1335. else
  1336. {
  1337. /*
  1338. * Set up the default (non client specific) keyboard input focus.
  1339. */
  1340. if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER)
  1341. {
  1342. focusWindow = PointerRoot;
  1343. }
  1344. else
  1345. {
  1346. /*
  1347. * The WORKSPACE_IF_NULL flag is used to prevent client
  1348. * windows from flashing when deiconifying a client.
  1349. */
  1350. if (WORKSPACE_IF_NULL & flags)
  1351. {
  1352. focusWindow = ACTIVE_PSD->wmWorkspaceWin;
  1353. }
  1354. else
  1355. {
  1356. /* find some reasonable client so that focus is not lost */
  1357. focusWindow = FindSomeReasonableClient();
  1358. if (focusWindow == (Window)NULL)
  1359. {
  1360. focusWindow = ACTIVE_PSD->wmWorkspaceWin;
  1361. }
  1362. }
  1363. }
  1364. }
  1365. if ((pcdFocus != wmGD.keyboardFocus) || (flags & ALWAYS_SET_FOCUS))
  1366. {
  1367. if (pcdFocus)
  1368. {
  1369. /*
  1370. * Set the focus and/or send a take focus client message. This
  1371. * is not done if a client area button press was done to set
  1372. * set the focus and the window is a globally active input
  1373. * style window (See ICCCM).
  1374. */
  1375. if ( (flags & CLIENT_AREA_FOCUS) &&
  1376. (pcdFocus->protocolFlags & PROTOCOL_WM_TAKE_FOCUS) &&
  1377. ! pcdFocus->inputFocusModel &&
  1378. (pcdFocus == pCD) &&
  1379. (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
  1380. !(pcdFocus->clientState == MINIMIZED_STATE)
  1381. )
  1382. {
  1383. /*
  1384. * We get here if:
  1385. * 1. User clicked in the client area AND
  1386. * 2. Input model is Globally Active AND
  1387. * 3. Keyboard focus policy is explicit
  1388. */
  1389. /* this window has WM_TAKE_FOCUS set and InputField false. */
  1390. /* just send a message. */
  1391. SendClientMsg (pcdFocus->client,
  1392. (long) wmGD.xa_WM_PROTOCOLS,
  1393. (long) wmGD.xa_WM_TAKE_FOCUS,
  1394. focusTime, NULL, 0);
  1395. }
  1396. else
  1397. {
  1398. if ((pcdFocus->protocolFlags & PROTOCOL_WM_TAKE_FOCUS) &&
  1399. !(pcdFocus->clientState == MINIMIZED_STATE))
  1400. {
  1401. /*
  1402. * Locally Active Input Model - Send a take focus message to the client.
  1403. */
  1404. SendClientMsg (pcdFocus->client,
  1405. (long) wmGD.xa_WM_PROTOCOLS,
  1406. (long) wmGD.xa_WM_TAKE_FOCUS,
  1407. focusTime, NULL, 0);
  1408. }
  1409. /*
  1410. * Don't set the input focus if the window has input_field set
  1411. * to False or has expressed an interest in WM_TAKE_FOCUS
  1412. * (ie. 'No Input', 'Globally Active', or 'Locally Active'),
  1413. * and the user click in the client area. If the user clicks
  1414. * on the titlebar or traverses to this window via f.next_key,
  1415. * set the focus so that the user can access the window menu
  1416. * and accelerators.
  1417. */
  1418. if ( wmGD.enforceKeyFocus || /* res - default == True. */
  1419. (flags & ALWAYS_SET_FOCUS) ||
  1420. !(flags & CLIENT_AREA_FOCUS)|| /* clicked on frame? */
  1421. pcdFocus->inputFocusModel || /* Pass.|Glob. Active */
  1422. (pcdFocus->clientState == MINIMIZED_STATE)
  1423. )
  1424. {
  1425. if ( !(flags & CLIENT_AREA_FOCUS) &&
  1426. !pcdFocus->inputFocusModel &&
  1427. !(pcdFocus->clientState == MINIMIZED_STATE))
  1428. {
  1429. /* the window doesn't want the focus - set it to the frame */
  1430. /* user clicked on the frame but we don't want the focus */
  1431. /* set it to the client's frame */
  1432. XSetInputFocus (DISPLAY, pcdFocus->clientBaseWin,
  1433. RevertToPointerRoot, focusTime);
  1434. }
  1435. else if ( !(flags & CLIENT_AREA_FOCUS) &&
  1436. !(pcdFocus->protocolFlags & PROTOCOL_WM_TAKE_FOCUS) &&
  1437. pcdFocus->inputFocusModel
  1438. )
  1439. {
  1440. XSetInputFocus (DISPLAY, focusWindow,
  1441. RevertToPointerRoot, focusTime);
  1442. }
  1443. else
  1444. {
  1445. XSetInputFocus (DISPLAY, focusWindow,
  1446. RevertToParent, focusTime);
  1447. }
  1448. }
  1449. else
  1450. {
  1451. /*
  1452. * We've decided that the window shouldn't get the focus,
  1453. * so don't change the focus.
  1454. */
  1455. pcdFocus = wmGD.nextKeyboardFocus;
  1456. }
  1457. }
  1458. }
  1459. else
  1460. {
  1461. XSetInputFocus (DISPLAY, focusWindow, RevertToPointerRoot,
  1462. focusTime);
  1463. }
  1464. wmGD.nextKeyboardFocus = pcdFocus;
  1465. }
  1466. } /* END OF FUNCTION Do_Focus_Key */
  1467. /***********************<->*************************************
  1468. *
  1469. * F_Goto_Workspace (args, pCD, event)
  1470. *
  1471. * Description:
  1472. * -----------
  1473. * This is the window manager function handler for switching
  1474. * to another workspace by name.
  1475. *
  1476. * Inputs:
  1477. * ------
  1478. * args = action function and arguments
  1479. *
  1480. * pCD = pointer to the ClientData
  1481. *
  1482. * event = X event that invoked the function (key, button, or menu/NULL)
  1483. *
  1484. * Outputs:
  1485. * -------
  1486. * Always False
  1487. *
  1488. * Comments:
  1489. * -------
  1490. ******************************<->***********************************/
  1491. Boolean
  1492. F_Goto_Workspace (String args, ClientData *pCD, XEvent *event)
  1493. {
  1494. WmScreenData *pSD = ACTIVE_PSD;
  1495. int iwsx;
  1496. XmString xms;
  1497. /*
  1498. * Compare argument against both resource name
  1499. * and workspace title, take the first match.
  1500. */
  1501. xms = XmStringCreate (args, XmFONTLIST_DEFAULT_TAG);
  1502. for (iwsx = 0; iwsx < pSD->numWorkspaces; iwsx++)
  1503. {
  1504. if (!strcmp(pSD->pWS[iwsx].name, args) ||
  1505. XmStringCompare (xms, pSD->pWS[iwsx].title))
  1506. {
  1507. break;
  1508. }
  1509. }
  1510. XmStringFree (xms);
  1511. /* check bounds */
  1512. if (iwsx >= pSD->numWorkspaces)
  1513. {
  1514. Warning (((char *)GETMESSAGE(26, 4,
  1515. "Invalid workspace name specified for f.goto_workspace")));
  1516. }
  1517. else
  1518. {
  1519. ChangeToWorkspace (&pSD->pWS[iwsx]);
  1520. }
  1521. return (False);
  1522. } /* END OF FUNCTION F_Goto_Workspace */
  1523. /******************************<->*************************************
  1524. *
  1525. * Boolean F_Help (String args, ClientData *pCD, XEvent *event)
  1526. *
  1527. * Description:
  1528. * -----------
  1529. * Invoke help on the workspace manager
  1530. *
  1531. * Inputs:
  1532. * ------
  1533. * args - incoming values
  1534. * pCD - associated client data structure
  1535. * event - what triggered this call
  1536. *
  1537. * Outputs:
  1538. * -------
  1539. * Return - True if the call occurs; false otherwise.
  1540. *
  1541. * Comments:
  1542. * --------
  1543. *
  1544. ******************************<->***********************************/
  1545. Boolean
  1546. F_Help (String args, ClientData *pCD, XEvent *event)
  1547. {
  1548. Boolean rval;
  1549. rval = WmDtHelp(args);
  1550. return (rval);
  1551. } /* END OF FUNCTION F_Help */
  1552. /******************************<->*************************************
  1553. *
  1554. * Boolean F_Help_Mode (String args, ClientData *pCD, XEvent *event)
  1555. *
  1556. * Description:
  1557. * -----------
  1558. * Invoke item help on the frontpanel
  1559. *
  1560. * Inputs:
  1561. * ------
  1562. * args - NULL
  1563. * pCD - associated client data structure ??
  1564. * event - what triggered this call
  1565. *
  1566. * Outputs:
  1567. * -------
  1568. * Return - True if the call occurs; false otherwise.
  1569. *
  1570. * Comments:
  1571. * --------
  1572. *
  1573. ******************************<->***********************************/
  1574. Boolean
  1575. F_Help_Mode (String args, ClientData *pCD, XEvent *event)
  1576. {
  1577. /*
  1578. * Help mode event processing interferes
  1579. * with slide up windows. Don't continue
  1580. * if windows are sliding.
  1581. */
  1582. if (wmGD.iSlideUpsInProgress == 0)
  1583. {
  1584. (void) WmDtHelpMode();
  1585. }
  1586. return (False);
  1587. } /* END OF FUNCTION F_Help_Mode */
  1588. /******************************<->*************************************
  1589. *
  1590. * F_Next_Key (args, pCD, event)
  1591. *
  1592. *
  1593. * Description:
  1594. * -----------
  1595. * This is the window manager function handler for setting the keyboard
  1596. * input focus to the next window in the set of managed windows.
  1597. *
  1598. *
  1599. * Inputs:
  1600. * ------
  1601. * args = (immediate value) window type flags
  1602. *
  1603. * pCD = pointer to the client data
  1604. *
  1605. * event = X event that invoked the function (key, button, or menu/NULL)
  1606. *
  1607. *************************************<->***********************************/
  1608. Boolean F_Next_Key (String args, ClientData *pCD, XEvent *event)
  1609. {
  1610. if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT)
  1611. {
  1612. FocusNextWindow ((unsigned long)args,
  1613. GetFunctionTimestamp ((XButtonEvent *)event));
  1614. }
  1615. return (True);
  1616. } /* END OF FUNCTION F_Next_Key */
  1617. /*************************************<->*************************************
  1618. *
  1619. * F_Prev_Cmap (args, pCD, event)
  1620. *
  1621. *
  1622. * Description:
  1623. * -----------
  1624. * This is the window manager function handler installing the previous
  1625. * colormap in the list of client window colormaps.
  1626. *
  1627. *************************************<->***********************************/
  1628. Boolean F_Prev_Cmap (String args, ClientData *pCD, XEvent *event)
  1629. {
  1630. if (pCD == NULL)
  1631. {
  1632. pCD = ACTIVE_PSD->colormapFocus;
  1633. }
  1634. if (pCD && (pCD->clientCmapCount > 0) &&
  1635. ((pCD->clientState == NORMAL_STATE) ||
  1636. (pCD->clientState == MAXIMIZED_STATE)))
  1637. {
  1638. if (--(pCD->clientCmapIndex) < 0)
  1639. {
  1640. pCD->clientCmapIndex = pCD->clientCmapCount - 1;
  1641. }
  1642. pCD->clientColormap = pCD->clientCmapList[pCD->clientCmapIndex];
  1643. if (ACTIVE_PSD->colormapFocus == pCD)
  1644. {
  1645. /*
  1646. * We just re-ordered the colormaps list,
  1647. * so we need to re-run the whole thing.
  1648. */
  1649. pCD->clientCmapFlagsInitialized = 0;
  1650. ProcessColormapList (ACTIVE_PSD, pCD);
  1651. }
  1652. }
  1653. return (True);
  1654. } /* END OF FUNCTION F_Prev_Cmap */
  1655. /*************************************<->*************************************
  1656. *
  1657. * F_Prev_Key (args, pCD, event)
  1658. *
  1659. *
  1660. * Description:
  1661. * -----------
  1662. * This is the window manager function handler for setting the keyboard
  1663. * input focus to the previous window in the set of managed windows.
  1664. *
  1665. *
  1666. * Inputs:
  1667. * ------
  1668. * args = (immediate value) window type flags
  1669. *
  1670. * pCD = pointer to the client data
  1671. *
  1672. * event = X event that invoked the function (key, button, or menu/NULL)
  1673. *
  1674. *************************************<->***********************************/
  1675. Boolean F_Prev_Key (String args, ClientData *pCD, XEvent *event)
  1676. {
  1677. if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT)
  1678. {
  1679. FocusPrevWindow ((unsigned long)args,
  1680. GetFunctionTimestamp ((XButtonEvent *)event));
  1681. }
  1682. return (True);
  1683. } /* END OF FUNCTION F_Prev_Key */
  1684. /***********************<->*************************************
  1685. *
  1686. * F_Post_FpMenu (args, pCD, event)
  1687. *
  1688. *
  1689. * Description:
  1690. * -----------
  1691. * This is the window manager function handler for posting
  1692. * the Front Panel window menu.
  1693. *
  1694. * Inputs:
  1695. * ------
  1696. * args = arguments (none)
  1697. *
  1698. * pCD = pointer to the FP ClientData
  1699. *
  1700. * event = X button press that invoked the function
  1701. *
  1702. ******************************<->***********************************/
  1703. Boolean
  1704. F_Post_FpMenu (String args, ClientData *pCD, XEvent *event)
  1705. {
  1706. static MenuSpec *fpMenuSpec = (MenuSpec *)NULL;
  1707. if (event->type != ButtonPress)
  1708. return False;
  1709. if (!fpMenuSpec)
  1710. {
  1711. WmScreenData *pSD = (pCD) ? PSD_FOR_CLIENT(pCD) : ACTIVE_PSD;
  1712. MenuSpec *oldSpec;
  1713. Widget tmpWidget;
  1714. char *newMenuName;
  1715. newMenuName = pCD ? pCD->systemMenu : "DtPanelMenu";
  1716. for (oldSpec = pSD->menuSpecs;
  1717. oldSpec != (MenuSpec *)NULL;
  1718. oldSpec = oldSpec->nextMenuSpec)
  1719. {
  1720. if (oldSpec->name && (strcmp(oldSpec->name, newMenuName) == 0))
  1721. break;
  1722. }
  1723. if (!oldSpec)
  1724. return False;
  1725. fpMenuSpec = DuplicateMenuSpec(oldSpec);
  1726. /*
  1727. * TEMPORARILY modify pSD so the new menu will be
  1728. * created on DISPLAY1 instead of DISPLAY.
  1729. */
  1730. fpMenuSpec->nextMenuSpec = pSD->menuSpecs;
  1731. pSD->menuSpecs = fpMenuSpec;
  1732. tmpWidget = pSD->screenTopLevelW;
  1733. pSD->screenTopLevelW = pSD->screenTopLevelW1;
  1734. (void)MAKE_MENU (pSD, pCD, newMenuName,
  1735. F_CONTEXT_NORMAL, F_CONTEXT_NORMAL,
  1736. (MenuItem *) NULL, FALSE);
  1737. /* Restore pSD */
  1738. pSD->screenTopLevelW = tmpWidget;
  1739. pSD->menuSpecs = fpMenuSpec->nextMenuSpec;
  1740. }
  1741. PostMenu (fpMenuSpec, pCD, event->xbutton.x_root, event->xbutton.y_root,
  1742. event->xbutton.button, F_CONTEXT_NORMAL, POST_AT_XY, event);
  1743. _XmGetMenuState(XtParent(fpMenuSpec->menuWidget))
  1744. ->MS_LastManagedMenuTime = event->xbutton.time;
  1745. return False;
  1746. }
  1747. /***********************<->*************************************
  1748. *
  1749. * F_Push_Recall (args, pCD, event)
  1750. *
  1751. *
  1752. * Description:
  1753. * -----------
  1754. * This is the window manager function handler for invoking/topping
  1755. * push_recall clients.
  1756. *
  1757. *
  1758. * Inputs:
  1759. * ------
  1760. * args = arguments
  1761. *
  1762. * pCD = pointer to the ClientData
  1763. *
  1764. * event = X event that invoked the function (key, button, or menu/NULL)
  1765. *
  1766. *
  1767. * Outputs:
  1768. * -------
  1769. * RETURN = if True then further button binding/function processing can
  1770. * be done for the event that caused this function to be called.
  1771. *
  1772. * Comments:
  1773. * -------
  1774. ******************************<->***********************************/
  1775. Boolean
  1776. F_Push_Recall (String args, ClientData *pCD, XEvent *event)
  1777. {
  1778. WmPushRecallArg *pPRP;
  1779. WmScreenData *pSD;
  1780. WmFpPushRecallClientData *pPRCD;
  1781. pPRP = (WmPushRecallArg *) args;
  1782. pSD = (pCD) ? PSD_FOR_CLIENT(pCD) : ACTIVE_PSD;
  1783. if (pPRP->ixReg < pSD->numPushRecallClients)
  1784. {
  1785. /* get slot for this client */
  1786. pPRCD = &(pSD->pPRCD[pPRP->ixReg]);
  1787. /*
  1788. * If the client is already running, then top it in this workspace,
  1789. * else invoke the function to start it.
  1790. */
  1791. if (pPRCD->pCD)
  1792. {
  1793. /* Client is managed already. */
  1794. if (!(ClientInWorkspace (pSD->pActiveWS, pPRCD->pCD)))
  1795. {
  1796. WorkspaceID *wsRemoveList;
  1797. int sizeRemoveList;
  1798. /*
  1799. * Move client to current workspace
  1800. */
  1801. wsRemoveList = GetListOfOccupiedWorkspaces (pPRCD->pCD,
  1802. &sizeRemoveList);
  1803. RemoveClientFromWorkspaces (pPRCD->pCD, wsRemoveList,
  1804. sizeRemoveList);
  1805. XtFree ((char *)wsRemoveList);
  1806. AddClientToWorkspaces (pPRCD->pCD, &(pSD->pActiveWS->id), 1);
  1807. SetClientWsIndex(pPRCD->pCD);
  1808. SetClientState(pPRCD->pCD,
  1809. pPRCD->pCD->clientState & ~UNSEEN_STATE, CurrentTime);
  1810. }
  1811. /* Make this client visible */
  1812. wmGD.bSuspendSecondaryRestack = True;
  1813. F_Normalize_And_Raise (NULL, pPRCD->pCD, event);
  1814. wmGD.bSuspendSecondaryRestack = False;
  1815. }
  1816. else
  1817. {
  1818. struct timeval tvNow;
  1819. struct timezone tz;
  1820. Boolean bWaiting = False;
  1821. if (pPRCD->tvTimeout.tv_sec != 0)
  1822. {
  1823. gettimeofday (&tvNow, &tz);
  1824. if ((pPRCD->tvTimeout.tv_sec > tvNow.tv_sec) ||
  1825. ((pPRCD->tvTimeout.tv_sec == tvNow.tv_sec) &&
  1826. (pPRCD->tvTimeout.tv_usec > tvNow.tv_usec)))
  1827. {
  1828. /* still waiting for client to start */
  1829. bWaiting = True;
  1830. }
  1831. }
  1832. if (!bWaiting)
  1833. {
  1834. long clientTimeout = 0;
  1835. Arg al[5];
  1836. int ac;
  1837. WmPanelistObject pPanelist;
  1838. pPanelist = (WmPanelistObject) pSD->wPanelist;
  1839. /* invoke the function to start the client */
  1840. pPRP->wmFunc ( pPRP->pArgs, pCD, event);
  1841. if (pPanelist && panel.busy_light_data)
  1842. {
  1843. /* set timeout value */
  1844. ac = 0;
  1845. XtSetArg (al[ac],
  1846. XmNclientTimeoutInterval, &clientTimeout); ac++;
  1847. XtGetValues (panel.busy_light_data->icon, (ArgList)al, ac);
  1848. }
  1849. /*
  1850. * ClientTimeout is in milliseconds, timeval values
  1851. * are in seconds and microseconds.
  1852. */
  1853. gettimeofday (&(pPRCD->tvTimeout), &tz);
  1854. pPRCD->tvTimeout.tv_sec += clientTimeout / 1000;
  1855. pPRCD->tvTimeout.tv_usec +=
  1856. (clientTimeout % 1000) * 1000;
  1857. pPRCD->tvTimeout.tv_sec += pPRCD->tvTimeout.tv_usec / 1000000;
  1858. pPRCD->tvTimeout.tv_usec %= 1000000;
  1859. }
  1860. }
  1861. }
  1862. return (True);
  1863. } /* END OF FUNCTION F_Push_Recall */
  1864. /*************************************<->*************************************
  1865. *
  1866. * F_Pass_Key (args, pCD, event)
  1867. *
  1868. *
  1869. * Description:
  1870. * -----------
  1871. * This is a function stub for the f.pass_key window manager function.
  1872. *
  1873. *
  1874. * Inputs:
  1875. * ------
  1876. * args = (immediate value) window type flags
  1877. *
  1878. * pCD = pointer to the client data
  1879. *
  1880. * event = X event that invoked the function (key, button, or menu/NULL)
  1881. *
  1882. *************************************<->***********************************/
  1883. Boolean F_Pass_Key (String args, ClientData *pCD, XEvent *event)
  1884. {
  1885. if (wmGD.passKeysActive)
  1886. {
  1887. /*
  1888. * Get out of pass keys mode.
  1889. */
  1890. wmGD.passKeysActive = False;
  1891. wmGD.passKeysKeySpec = NULL;
  1892. }
  1893. else
  1894. {
  1895. /*
  1896. * Get into pass keys mode.
  1897. */
  1898. wmGD.passKeysActive = True;
  1899. }
  1900. return (False);
  1901. } /* END OF FUNCTION F_Pass_Key */
  1902. /*************************************<->*************************************
  1903. *
  1904. * F_Maximize (args, pCD, event)
  1905. *
  1906. *
  1907. * Description:
  1908. * -----------
  1909. * This is the window manager function handler for maximizing a client
  1910. * window.
  1911. *
  1912. *************************************<->***********************************/
  1913. Boolean F_Maximize (String args, ClientData *pCD, XEvent *event)
  1914. {
  1915. if (pCD && (pCD->clientFunctions & MWM_FUNC_MAXIMIZE))
  1916. {
  1917. SetClientStateWithEventMask (pCD, MAXIMIZED_STATE,
  1918. GetFunctionTimestamp ((XButtonEvent *)event),
  1919. GetEventInverseMask(event));
  1920. }
  1921. return (False);
  1922. } /* END OF FUNCTION F_Maximize */
  1923. /*************************************<->*************************************
  1924. *
  1925. * F_Menu (args, pCD, event)
  1926. *
  1927. *
  1928. * Description:
  1929. * -----------
  1930. * This is the window manager function handler for posting a menu.
  1931. * This function can only be invoked by a key or button event.
  1932. * wmGD.menuUnpostKeySpec is assumed set appropriately; it will be set to
  1933. * NULL when the menu is unposted.
  1934. *
  1935. *************************************<->***********************************/
  1936. Boolean F_Menu (String args, ClientData *pCD, XEvent *event)
  1937. {
  1938. MenuSpec *menuSpec;
  1939. Context menuContext;
  1940. unsigned int button;
  1941. int x;
  1942. int y;
  1943. long flags = POST_AT_XY;
  1944. WmScreenData *pSD;
  1945. if (event &&
  1946. ((event->type == ButtonPress) || (event->type == ButtonRelease)))
  1947. {
  1948. button = event->xbutton.button;
  1949. x = event->xbutton.x_root;
  1950. y = event->xbutton.y_root;
  1951. if (event->type == ButtonRelease)
  1952. {
  1953. flags |= POST_TRAVERSAL_ON;
  1954. }
  1955. /*
  1956. * Root menu, if posted with button press, then
  1957. * set up to handle root menu click to make the menu
  1958. * sticky.
  1959. */
  1960. else if (wmGD.rootButtonClick && (event->type == ButtonPress))
  1961. {
  1962. if (wmGD.bReplayedButton)
  1963. {
  1964. /* This button was replayed, it most likely dismissed
  1965. a previous sticky menu, don't post a menu here */
  1966. return (False);
  1967. }
  1968. wmGD.checkHotspot = True;
  1969. wmGD.hotspotRectangle.x = x - wmGD.moveThreshold/2;
  1970. wmGD.hotspotRectangle.y = y - wmGD.moveThreshold/2;
  1971. wmGD.hotspotRectangle.width = wmGD.moveThreshold;
  1972. wmGD.hotspotRectangle.height = wmGD.moveThreshold;
  1973. }
  1974. }
  1975. else if (event &&
  1976. ((event->type == KeyPress) || (event->type == KeyRelease)))
  1977. {
  1978. button = NoButton;
  1979. x = event->xkey.x_root;
  1980. y = event->xkey.y_root;
  1981. }
  1982. else
  1983. {
  1984. /*
  1985. * A button or key event must be used to post a menu using this
  1986. * function.
  1987. */
  1988. return (False);
  1989. }
  1990. if (pCD)
  1991. {
  1992. if (pCD->clientState == NORMAL_STATE)
  1993. {
  1994. menuContext = F_CONTEXT_NORMAL;
  1995. }
  1996. else if (pCD->clientState == MAXIMIZED_STATE)
  1997. {
  1998. menuContext = F_CONTEXT_MAXIMIZE;
  1999. }
  2000. else
  2001. {
  2002. menuContext = F_CONTEXT_ICON;
  2003. }
  2004. if (P_ICON_BOX(pCD) &&
  2005. event->xany.window == ICON_FRAME_WIN(pCD))
  2006. {
  2007. if (pCD->clientState == MINIMIZED_STATE)
  2008. {
  2009. menuContext = F_SUBCONTEXT_IB_IICON;
  2010. }
  2011. else
  2012. {
  2013. menuContext = F_SUBCONTEXT_IB_WICON;
  2014. }
  2015. }
  2016. }
  2017. else
  2018. {
  2019. menuContext = F_CONTEXT_ROOT;
  2020. }
  2021. /* We do not add this MenuSpec to wmGD.acceleratorMenuSpecs.
  2022. * This should have been done in MakeWmFunctionResources().
  2023. */
  2024. pSD = (pCD) ? PSD_FOR_CLIENT(pCD) : ACTIVE_PSD;
  2025. if ((menuSpec = MAKE_MENU (pSD, pCD, args, menuContext,
  2026. menuContext, (MenuItem *) NULL, FALSE)) != NULL)
  2027. {
  2028. PostMenu (menuSpec, pCD, x, y, button, menuContext, flags, event);
  2029. }
  2030. return (False);
  2031. } /* END OF FUNCTION F_Menu */
  2032. /*************************************<->*************************************
  2033. *
  2034. * F_Minimize (args, pCD, event)
  2035. *
  2036. *
  2037. * Description:
  2038. * -----------
  2039. * This is the window manager function handler for minimizing a client
  2040. * window.
  2041. *
  2042. *************************************<->***********************************/
  2043. Boolean F_Minimize (String args, ClientData *pCD, XEvent *event)
  2044. {
  2045. ClientData *pcdLeader;
  2046. if (pCD)
  2047. {
  2048. /*
  2049. * If the window is a transient then minimize the entire transient
  2050. * tree including the transient leader.
  2051. */
  2052. pcdLeader = (pCD->transientLeader) ?
  2053. FindTransientTreeLeader (pCD) : pCD;
  2054. if (pcdLeader->clientFunctions & MWM_FUNC_MINIMIZE)
  2055. {
  2056. SetClientStateWithEventMask (pCD, MINIMIZED_STATE,
  2057. GetFunctionTimestamp ((XButtonEvent *)event),
  2058. GetEventInverseMask(event));
  2059. }
  2060. }
  2061. return (False);
  2062. } /* END OF FUNCTION F_Minimize */
  2063. /*************************************<->*************************************
  2064. *
  2065. * F_Move (args, pCD, event)
  2066. *
  2067. *
  2068. * Description:
  2069. * -----------
  2070. * This is the window manager function handler for moving a client window
  2071. * or icon.
  2072. *
  2073. *************************************<->***********************************/
  2074. Boolean F_Move (String args, ClientData *pCD, XEvent *event)
  2075. {
  2076. if (pCD && (pCD->clientFunctions & MWM_FUNC_MOVE))
  2077. {
  2078. StartClientMove (pCD, event);
  2079. HandleClientFrameMove (pCD, event);
  2080. }
  2081. return (False);
  2082. } /* END OF FUNCTION F_Move */
  2083. /*************************************<->*************************************
  2084. *
  2085. * F_Next_Cmap (args, pCD, event)
  2086. *
  2087. *
  2088. * Description:
  2089. * -----------
  2090. * This is the window manager function handler installing the next
  2091. * colormap in the list of client window colormaps.
  2092. *
  2093. *************************************<->***********************************/
  2094. Boolean F_Next_Cmap (String args, ClientData *pCD, XEvent *event)
  2095. {
  2096. if (pCD == NULL)
  2097. {
  2098. pCD = ACTIVE_PSD->colormapFocus;
  2099. }
  2100. if (pCD && (pCD->clientCmapCount > 0) &&
  2101. ((pCD->clientState == NORMAL_STATE) ||
  2102. (pCD->clientState == MAXIMIZED_STATE)))
  2103. {
  2104. if (++(pCD->clientCmapIndex) >= pCD->clientCmapCount)
  2105. {
  2106. pCD->clientCmapIndex = 0;
  2107. }
  2108. pCD->clientColormap = pCD->clientCmapList[pCD->clientCmapIndex];
  2109. if (ACTIVE_PSD->colormapFocus == pCD)
  2110. {
  2111. /*
  2112. * We just re-ordered the colormaps list,
  2113. * so we need to re-run the whole thing.
  2114. */
  2115. pCD->clientCmapFlagsInitialized = 0;
  2116. ProcessColormapList (ACTIVE_PSD, pCD);
  2117. }
  2118. }
  2119. return (True);
  2120. } /* END OF FUNCTION F_Next_Cmap */
  2121. /*************************************<->*************************************
  2122. *
  2123. * F_Nop (args, pCD, event)
  2124. *
  2125. *
  2126. * Description:
  2127. * -----------
  2128. * This is the window manager function handler for doing nothing.
  2129. *
  2130. *************************************<->***********************************/
  2131. Boolean F_Nop (String args, ClientData *pCD, XEvent *event)
  2132. {
  2133. return (True);
  2134. } /* END OF FUNCTION F_Nop */
  2135. /*************************************<->*************************************
  2136. *
  2137. * F_Normalize (args, pCD, event)
  2138. *
  2139. *
  2140. * Description:
  2141. * -----------
  2142. * This is the window manager function handler for putting a client window
  2143. * in the normal state.
  2144. *
  2145. *************************************<->***********************************/
  2146. Boolean F_Normalize (String args, ClientData *pCD, XEvent *event)
  2147. {
  2148. if (pCD)
  2149. {
  2150. SetClientStateWithEventMask (pCD, NORMAL_STATE,
  2151. GetFunctionTimestamp ((XButtonEvent *)event),
  2152. GetEventInverseMask(event));
  2153. }
  2154. return (False);
  2155. } /* END OF FUNCTION F_Normalize */
  2156. /*************************************<->*************************************
  2157. *
  2158. * F_Normalize_And_Raise (args, pCD, event)
  2159. *
  2160. *
  2161. * Description:
  2162. * -----------
  2163. * This is the window manager function handler for putting a client window
  2164. * in the normal state and raising it from and icon.
  2165. *
  2166. *************************************<->***********************************/
  2167. Boolean F_Normalize_And_Raise (String args, ClientData *pCD, XEvent *event)
  2168. {
  2169. WmScreenData *pSD;
  2170. WmWorkspaceData *pWS;
  2171. if (args)
  2172. {
  2173. if (pCD)
  2174. pSD = PSD_FOR_CLIENT (pCD);
  2175. else
  2176. pSD = ACTIVE_PSD;
  2177. pWS = pSD->pActiveWS;
  2178. if (pSD->useIconBox &&
  2179. wmGD.useFrontPanel &&
  2180. pSD->iconBoxControl &&
  2181. (!strcmp(args, WmNiconBox)))
  2182. {
  2183. /*
  2184. * There's an icon box in the front panel and this is a
  2185. * request to pop up the icon box.
  2186. */
  2187. IconBoxPopUp (pWS, True);
  2188. return (False);
  2189. }
  2190. }
  2191. if (pCD)
  2192. {
  2193. if (pCD->clientState == MINIMIZED_STATE)
  2194. {
  2195. /* normalize window */
  2196. SetClientStateWithEventMask (pCD, NORMAL_STATE,
  2197. (Time)
  2198. (event
  2199. ? GetFunctionTimestamp ((XButtonEvent *)event)
  2200. : GetTimestamp ()),
  2201. GetEventInverseMask(event));
  2202. }
  2203. else
  2204. {
  2205. /* Make sure we are in NORMAL_STATE */
  2206. SetClientStateWithEventMask (pCD, NORMAL_STATE,
  2207. GetFunctionTimestamp ((XButtonEvent *)event),
  2208. GetEventInverseMask(event));
  2209. /* Raise the window and set the keyboard focus to the window */
  2210. wmGD.bSuspendSecondaryRestack = True;
  2211. F_Raise (NULL, pCD, (XEvent *)NULL);
  2212. wmGD.bSuspendSecondaryRestack = False;
  2213. if (wmGD.raiseKeyFocus)
  2214. {
  2215. F_Focus_Key (NULL, pCD,
  2216. (event
  2217. ? ((XEvent *)event)
  2218. : ((XEvent *)NULL)));
  2219. }
  2220. }
  2221. wmGD.clickData.clickPending = False;
  2222. wmGD.clickData.doubleClickPending = False;
  2223. }
  2224. return (False);
  2225. } /* END OF FUNCTION F_Normalize_And_Raise */
  2226. /*************************************<->*************************************
  2227. *
  2228. * F_Restore (args, pCD, event)
  2229. *
  2230. *
  2231. * Description:
  2232. * -----------
  2233. * This is the window manager function handler for putting a client window
  2234. * in the normal state.
  2235. *
  2236. *************************************<->***********************************/
  2237. Boolean F_Restore (String args, ClientData *pCD, XEvent *event)
  2238. {
  2239. int newState;
  2240. if (pCD)
  2241. {
  2242. /*
  2243. * If current state is MAXIMIZED state then just go to NORMAL state,
  2244. * otherwise (you are in MINIMIZED state) return to previous state.
  2245. */
  2246. if (pCD->clientState == MAXIMIZED_STATE)
  2247. {
  2248. SetClientStateWithEventMask (pCD, NORMAL_STATE,
  2249. GetFunctionTimestamp ((XButtonEvent *)event),
  2250. GetEventInverseMask(event));
  2251. }
  2252. else
  2253. {
  2254. if (pCD->maxConfig)
  2255. {
  2256. newState = MAXIMIZED_STATE;
  2257. }
  2258. else
  2259. {
  2260. newState = NORMAL_STATE;
  2261. }
  2262. SetClientStateWithEventMask (pCD, newState,
  2263. GetFunctionTimestamp ((XButtonEvent *)event),
  2264. GetEventInverseMask(event));
  2265. }
  2266. }
  2267. return (False);
  2268. } /* END OF FUNCTION F_Restore */
  2269. /*************************************<->*************************************
  2270. *
  2271. * F_Restore_And_Raise (args, pCD, event)
  2272. *
  2273. *
  2274. * Description:
  2275. * -----------
  2276. * This is the window manager function handler for putting a client window
  2277. * in the normal state and raising it from and icon.
  2278. *
  2279. *************************************<->***********************************/
  2280. Boolean F_Restore_And_Raise (String args, ClientData *pCD, XEvent *event)
  2281. {
  2282. int newState;
  2283. if (pCD)
  2284. {
  2285. if (pCD->clientState == MINIMIZED_STATE)
  2286. {
  2287. /* Restore window */
  2288. if (pCD->maxConfig)
  2289. {
  2290. newState = MAXIMIZED_STATE;
  2291. }
  2292. else
  2293. {
  2294. newState = NORMAL_STATE;
  2295. }
  2296. SetClientStateWithEventMask (pCD, newState,
  2297. (Time)
  2298. (event
  2299. ? GetFunctionTimestamp ((XButtonEvent *)event)
  2300. : GetTimestamp ()),
  2301. GetEventInverseMask(event));
  2302. }
  2303. else
  2304. {
  2305. /* Make sure we restore the window first */
  2306. F_Restore (NULL, pCD, event);
  2307. /* Raise the window and set the keyboard focus to the window */
  2308. wmGD.bSuspendSecondaryRestack = True;
  2309. F_Raise (NULL, pCD, (XEvent *)NULL);
  2310. wmGD.bSuspendSecondaryRestack = False;
  2311. if (wmGD.raiseKeyFocus)
  2312. {
  2313. F_Focus_Key (NULL, pCD,
  2314. (event
  2315. ? ((XEvent *)event)
  2316. : ((XEvent *)NULL)));
  2317. }
  2318. }
  2319. wmGD.clickData.clickPending = False;
  2320. wmGD.clickData.doubleClickPending = False;
  2321. }
  2322. return (False);
  2323. } /* END OF FUNCTION F_Restore_And_Raise */
  2324. /*************************************<->*************************************
  2325. *
  2326. * F_Pack_Icons (args, pCD, event)
  2327. *
  2328. *
  2329. * Description:
  2330. * -----------
  2331. * This is the window manager function handler for packing icons in the
  2332. * icon box or on the desktop.
  2333. *
  2334. *************************************<->***********************************/
  2335. Boolean F_Pack_Icons (String args, ClientData *pCD, XEvent *event)
  2336. {
  2337. IconBoxData *pIBD;
  2338. if (ACTIVE_PSD->useIconBox)
  2339. {
  2340. pIBD = ACTIVE_WS->pIconBox;
  2341. if (pCD)
  2342. {
  2343. while (pCD != pIBD->pCD_iconBox)
  2344. {
  2345. if (pIBD->pNextIconBox)
  2346. {
  2347. pIBD = pIBD->pNextIconBox;
  2348. }
  2349. else
  2350. {
  2351. pIBD = NULL;
  2352. break;
  2353. }
  2354. }
  2355. }
  2356. if (pIBD)
  2357. {
  2358. PackIconBox (pIBD, False, False, 0, 0);
  2359. }
  2360. else
  2361. {
  2362. PackRootIcons ();
  2363. }
  2364. }
  2365. else
  2366. {
  2367. PackRootIcons ();
  2368. }
  2369. return (True);
  2370. } /* END OF FUNCTION F_Pack_Icons */
  2371. /*************************************<->*************************************
  2372. *
  2373. * F_Post_SMenu (args, pCD, event)
  2374. *
  2375. *
  2376. * Description:
  2377. * -----------
  2378. * This is the window manager function handler for posting the system menu
  2379. * for the specified client.
  2380. * This function can only be invoked by a key or button event.
  2381. * wmGD.menuUnpostKeySpec is assumed set appropriately; it will be set to
  2382. * NULL when the menu is unposted.
  2383. *
  2384. *************************************<->***********************************/
  2385. Boolean F_Post_SMenu (String args, ClientData *pCD, XEvent *event)
  2386. {
  2387. Context menuContext;
  2388. /*
  2389. * An event must be used to post the system menu using this function.
  2390. */
  2391. if (event && pCD && pCD->systemMenuSpec)
  2392. {
  2393. /*
  2394. * Determine whether the keyboard is posting the menu and post
  2395. * the menu at an appropriate place.
  2396. */
  2397. if (pCD->clientState == NORMAL_STATE)
  2398. {
  2399. menuContext = F_CONTEXT_NORMAL;
  2400. }
  2401. else if (pCD->clientState == MAXIMIZED_STATE)
  2402. {
  2403. menuContext = F_CONTEXT_MAXIMIZE;
  2404. }
  2405. else
  2406. {
  2407. menuContext = F_CONTEXT_ICON;
  2408. }
  2409. if (P_ICON_BOX(pCD) &&
  2410. event->xany.window == ICON_FRAME_WIN(pCD))
  2411. {
  2412. if (pCD->clientState == MINIMIZED_STATE)
  2413. {
  2414. menuContext = F_SUBCONTEXT_IB_IICON;
  2415. }
  2416. else
  2417. {
  2418. menuContext = F_SUBCONTEXT_IB_WICON;
  2419. }
  2420. }
  2421. if ((event->type == KeyPress) || (event->type == KeyRelease))
  2422. {
  2423. /*
  2424. * Set up for "sticky" menu processing if specified.
  2425. */
  2426. if (pCD->clientState == MINIMIZED_STATE ||
  2427. menuContext == (F_SUBCONTEXT_IB_IICON | F_SUBCONTEXT_IB_WICON))
  2428. {
  2429. if (wmGD.iconClick)
  2430. {
  2431. wmGD.checkHotspot = True;
  2432. }
  2433. }
  2434. else if (wmGD.systemButtonClick && (pCD->decor & MWM_DECOR_MENU))
  2435. {
  2436. wmGD.checkHotspot = True;
  2437. }
  2438. PostMenu (pCD->systemMenuSpec, pCD, 0, 0, NoButton, menuContext,
  2439. 0, event);
  2440. }
  2441. else if (event->type == ButtonPress)
  2442. {
  2443. /*
  2444. * Root menu, if posted with button press, then
  2445. * set up to handle root menu click to make the menu
  2446. * sticky.
  2447. */
  2448. if (wmGD.rootButtonClick && (!wmGD.checkHotspot))
  2449. {
  2450. wmGD.checkHotspot = True;
  2451. wmGD.hotspotRectangle.x =
  2452. event->xbutton.x_root - wmGD.moveThreshold/2;
  2453. wmGD.hotspotRectangle.y =
  2454. event->xbutton.y_root - wmGD.moveThreshold/2;
  2455. wmGD.hotspotRectangle.width = wmGD.moveThreshold;
  2456. wmGD.hotspotRectangle.height = wmGD.moveThreshold;
  2457. }
  2458. PostMenu (pCD->systemMenuSpec, pCD,
  2459. event->xbutton.x_root, event->xbutton.y_root,
  2460. event->xbutton.button, menuContext, POST_AT_XY, event);
  2461. }
  2462. else if (event->type == ButtonRelease)
  2463. {
  2464. PostMenu (pCD->systemMenuSpec, pCD,
  2465. event->xbutton.x_root, event->xbutton.y_root,
  2466. event->xbutton.button, menuContext,
  2467. POST_AT_XY | POST_TRAVERSAL_ON, event);
  2468. }
  2469. }
  2470. return (False);
  2471. } /* END OF FUNCTION F_PostSMenu */
  2472. /*************************************<->*************************************
  2473. *
  2474. * F_Kill (args, pCD, event)
  2475. *
  2476. *
  2477. * Description:
  2478. * -----------
  2479. * This is the window manager function handler for terminating a client.
  2480. * Essentially the client connection is shut down.
  2481. *
  2482. *************************************<->***********************************/
  2483. Boolean F_Kill (String args, ClientData *pCD, XEvent *event)
  2484. {
  2485. if (pCD && (pCD->clientFunctions & MWM_FUNC_CLOSE))
  2486. {
  2487. Boolean do_delete_window =
  2488. pCD->protocolFlags & PROTOCOL_WM_DELETE_WINDOW;
  2489. Boolean do_save_yourself =
  2490. pCD->protocolFlags & PROTOCOL_WM_SAVE_YOURSELF;
  2491. if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL)
  2492. {
  2493. Widget wPanel;
  2494. /*
  2495. * Get the widget for the subpanel
  2496. * (Should be only child of the shell!)
  2497. */
  2498. wPanel = WmPanelistWindowToSubpanel (DISPLAY1, pCD->client);
  2499. if (wPanel)
  2500. {
  2501. SlideSubpanelBackIn (pCD, wPanel);
  2502. }
  2503. return (False);
  2504. }
  2505. if (pCD->clientFlags & ICON_BOX)
  2506. {
  2507. /*
  2508. * When the front panel is used with the icon box,
  2509. * "Close" hides the icon box into the front panel.
  2510. */
  2511. if ((wmGD.useFrontPanel) &&
  2512. (pCD->pSD->iconBoxControl) &&
  2513. (IconBoxShowing(pCD->pSD->pActiveWS)))
  2514. {
  2515. IconBoxPopUp (pCD->pSD->pActiveWS, False);
  2516. }
  2517. }
  2518. else if (!do_delete_window && !do_save_yourself)
  2519. {
  2520. XKillClient (DISPLAY, pCD->client);
  2521. }
  2522. else
  2523. {
  2524. if (do_delete_window)
  2525. {
  2526. /*
  2527. * The client wants to be notified, not killed.
  2528. */
  2529. SendClientMsg (pCD->client, (long) wmGD.xa_WM_PROTOCOLS,
  2530. (long) wmGD.xa_WM_DELETE_WINDOW, CurrentTime, NULL, 0);
  2531. }
  2532. /*
  2533. * HP does not want to send a client message for both
  2534. * delete_window AND save_yourself. The current OSF
  2535. * patch did just that. This "else if" returns dtwm
  2536. * to the behavior of dt 2.01
  2537. */
  2538. else if (do_save_yourself)
  2539. {
  2540. /*
  2541. * Send a WM_SAVE_YOURSELF message and wait for a change to
  2542. * the WM_COMMAND property.
  2543. * !!! button and key input should be kept from the window !!!
  2544. */
  2545. if (AddWmTimer (TIMER_QUIT,
  2546. (unsigned long) wmGD.quitTimeout, pCD))
  2547. {
  2548. SendClientMsg (pCD->client, (long) wmGD.xa_WM_PROTOCOLS,
  2549. (long) wmGD.xa_WM_SAVE_YOURSELF, CurrentTime, NULL, 0);
  2550. pCD->clientFlags |= CLIENT_TERMINATING;
  2551. }
  2552. else
  2553. {
  2554. XKillClient (DISPLAY, pCD->client);
  2555. }
  2556. }
  2557. }
  2558. }
  2559. return (False);
  2560. } /* END OF FUNCTION F_Kill */
  2561. /*************************************<->*************************************
  2562. *
  2563. * F_Marquee_Selection (args, pCD, event)
  2564. *
  2565. *
  2566. * Description:
  2567. * -----------
  2568. * This is the window manager function handler for selecting
  2569. * non-window manager objects on the root window.
  2570. *
  2571. *************************************<->***********************************/
  2572. Boolean F_Marquee_Selection (String args, ClientData *pCD, XEvent *event)
  2573. {
  2574. if (!pCD)
  2575. {
  2576. /*
  2577. * This function only valid in root context
  2578. */
  2579. StartMarqueeSelect (ACTIVE_PSD, event);
  2580. HandleMarqueeSelect (ACTIVE_PSD, event);
  2581. }
  2582. return (False);
  2583. } /* END OF FUNCTION F_Marquee_Selection */
  2584. /*************************************<->*************************************
  2585. *
  2586. * RefreshByClearing (win)
  2587. *
  2588. *
  2589. * Description:
  2590. * -----------
  2591. * Recursively refresh this window and its children by doing
  2592. * XClearAreas
  2593. *
  2594. *************************************<->***********************************/
  2595. static void
  2596. RefreshByClearing (Window win)
  2597. {
  2598. Status status;
  2599. int i;
  2600. Window root, parent;
  2601. unsigned int nchildren;
  2602. Window *winChildren;
  2603. /* clear this window */
  2604. XClearArea(DISPLAY, win, 0, 0, 0, 0, True);
  2605. /* find any children and clear them, too */
  2606. status = XQueryTree(DISPLAY, win, &root, &parent, &winChildren,
  2607. &nchildren);
  2608. if (status != 0)
  2609. {
  2610. /* recurse for each child window */
  2611. for (i=0; i<nchildren; ++i)
  2612. {
  2613. RefreshByClearing(winChildren[i]);
  2614. }
  2615. /* clean up */
  2616. if (nchildren > 0)
  2617. XFree((char *)winChildren);
  2618. }
  2619. }
  2620. /*************************************<->*************************************
  2621. *
  2622. * F_Refresh (args, pCD, event)
  2623. *
  2624. *
  2625. * Description:
  2626. * -----------
  2627. * This is the window manager function handler for causing all windows
  2628. * in the workspace to be redrawn.
  2629. *
  2630. *************************************<->***********************************/
  2631. Boolean F_Refresh (String args, ClientData *pCD, XEvent *event)
  2632. {
  2633. Window win;
  2634. if (wmGD.refreshByClearing)
  2635. {
  2636. RefreshByClearing (ACTIVE_ROOT);
  2637. }
  2638. else
  2639. {
  2640. /* default background_pixmap is None */
  2641. win = XCreateWindow (DISPLAY,
  2642. ACTIVE_ROOT, 0, 0,
  2643. (unsigned int) DisplayWidth (DISPLAY,
  2644. ACTIVE_SCREEN),
  2645. (unsigned int) DisplayHeight (DISPLAY,
  2646. ACTIVE_SCREEN),
  2647. 0,
  2648. 0,
  2649. InputOutput,
  2650. CopyFromParent,
  2651. 0,
  2652. (XSetWindowAttributes *)NULL);
  2653. XMapWindow (DISPLAY, win);
  2654. XDestroyWindow (DISPLAY, win);
  2655. }
  2656. XFlush (DISPLAY);
  2657. return (True);
  2658. } /* END OF FUNCTION F_Refresh */
  2659. /*************************************<->*************************************
  2660. *
  2661. * F_Resize (args, pCD, event)
  2662. *
  2663. *
  2664. * Description:
  2665. * -----------
  2666. * This is the window manager function handler for resizing a client window.
  2667. *
  2668. *************************************<->***********************************/
  2669. Boolean F_Resize (String args, ClientData *pCD, XEvent *event)
  2670. {
  2671. if (pCD && (pCD->clientFunctions & MWM_FUNC_RESIZE) &&
  2672. ((pCD->clientState == NORMAL_STATE) ||
  2673. (pCD->clientState == MAXIMIZED_STATE)))
  2674. {
  2675. StartClientResize (pCD, event);
  2676. HandleClientFrameResize (pCD, event);
  2677. }
  2678. return (False);
  2679. } /* END OF FUNCTION F_Resize */
  2680. /*************************************<->*************************************
  2681. *
  2682. * F_Restart (args, pCD, event)
  2683. *
  2684. *
  2685. * Description:
  2686. * -----------
  2687. * This is the window manager function handler for restarting the window
  2688. * manager.
  2689. *
  2690. *************************************<->***********************************/
  2691. Boolean F_Restart (String args, ClientData *pCD, XEvent *event)
  2692. {
  2693. if (args && *args && !strcmp (args, DTWM_REQP_NO_CONFIRM))
  2694. {
  2695. RestartWm (MWM_INFO_STARTUP_CUSTOM);
  2696. }
  2697. else if (wmGD.showFeedback & WM_SHOW_FB_RESTART)
  2698. {
  2699. ConfirmAction (ACTIVE_PSD, RESTART_ACTION);
  2700. }
  2701. else
  2702. {
  2703. RestartWm (MWM_INFO_STARTUP_CUSTOM);
  2704. }
  2705. return (False);
  2706. } /* END OF FUNCTION F_Restart */
  2707. /*************************************<->*************************************
  2708. *
  2709. * Do_Restart (dummy)
  2710. *
  2711. *
  2712. * Description:
  2713. * -----------
  2714. * Callback function for restarting the window manager.
  2715. *
  2716. *************************************<->***********************************/
  2717. void Do_Restart (Boolean dummy)
  2718. {
  2719. RestartWm (MWM_INFO_STARTUP_CUSTOM);
  2720. } /* END OF FUNCTION Do_Restart */
  2721. /*************************************<->*************************************
  2722. *
  2723. * RestartWm (startupFlags)
  2724. *
  2725. *
  2726. * Description:
  2727. * -----------
  2728. * Actually restarts the window manager.
  2729. *
  2730. *
  2731. * Inputs:
  2732. * ------
  2733. * startupFlags = flags to be put into the Wm_INFO property for restart.
  2734. *
  2735. *************************************<->***********************************/
  2736. void RestartWm (long startupFlags)
  2737. {
  2738. ClientListEntry *pNextEntry;
  2739. int scr;
  2740. for (scr=0; scr<wmGD.numScreens; scr++)
  2741. {
  2742. if(wmGD.Screens[scr].managed)
  2743. {
  2744. /*
  2745. * Set up the _MOTIF_WM_INFO property on the root window
  2746. * to indicate a restart.
  2747. */
  2748. SetMwmInfo (wmGD.Screens[scr].rootWindow, startupFlags, 0);
  2749. SaveResources(&wmGD.Screens[scr]);
  2750. /*
  2751. * Unmap client windows and reparent them to the root window.
  2752. */
  2753. pNextEntry = wmGD.Screens[scr].lastClient;
  2754. while (pNextEntry)
  2755. {
  2756. if (pNextEntry->type == NORMAL_STATE)
  2757. {
  2758. if (pNextEntry->pCD->clientFlags & CLIENT_WM_CLIENTS)
  2759. {
  2760. if (pNextEntry->pCD->clientState != MINIMIZED_STATE)
  2761. {
  2762. XUnmapWindow (DISPLAY,
  2763. pNextEntry->pCD->clientFrameWin);
  2764. }
  2765. }
  2766. else
  2767. {
  2768. DeFrameClient (pNextEntry->pCD);
  2769. }
  2770. }
  2771. pNextEntry = pNextEntry->prevSibling;
  2772. }
  2773. UnParentControls (&wmGD.Screens[scr], True);
  2774. }
  2775. }
  2776. /* shut down the messaging connection */
  2777. dtCloseIPC();
  2778. ResignFromSM();
  2779. /*
  2780. * This fixes restart problem when going from explicit focus to
  2781. * pointer focus. Window under pointer was not getting focus indication
  2782. * until pointer was moved to new window, or out of and into the
  2783. * window.
  2784. */
  2785. XSetInputFocus (DISPLAY, PointerRoot, RevertToPointerRoot, CurrentTime);
  2786. XSync (DISPLAY, False);
  2787. CLOSE_FILES_ON_EXEC();
  2788. _DtEnvControl(DT_ENV_RESTORE_PRE_DT);
  2789. /*
  2790. * Restart the window manager with the initial arguments plus
  2791. * the restart settings.
  2792. */
  2793. execvp (*(wmGD.argv), wmGD.argv);
  2794. Warning (((char *)GETMESSAGE(26, 1,
  2795. "The window manager restart failed. The window manager program could not \
  2796. be found or could not be executed.")));
  2797. Do_Quit_Mwm (True);
  2798. } /* END OF FUNCTION RestartWm */
  2799. /*************************************<->*************************************
  2800. *
  2801. * DeFrameClient (pCD)
  2802. *
  2803. *
  2804. * Description:
  2805. * -----------
  2806. * Unmaps a client window (and client icon window) and reparents the
  2807. * window back to the root.
  2808. *
  2809. *
  2810. * Inputs:
  2811. * -------
  2812. * pCD = pointer to the client data for the window to be de-framed.
  2813. *
  2814. *************************************<->***********************************/
  2815. void DeFrameClient (ClientData *pCD)
  2816. {
  2817. int x, y;
  2818. int xoff, yoff;
  2819. XWindowChanges windowChanges;
  2820. while (pCD)
  2821. {
  2822. if (pCD->clientState != MINIMIZED_STATE)
  2823. {
  2824. XUnmapWindow (DISPLAY, pCD->clientFrameWin);
  2825. }
  2826. if (pCD->iconWindow && (pCD->clientFlags & ICON_REPARENTED))
  2827. {
  2828. XUnmapWindow (DISPLAY, pCD->iconWindow);
  2829. XRemoveFromSaveSet (DISPLAY, pCD->iconWindow);
  2830. XReparentWindow (DISPLAY, pCD->iconWindow,
  2831. ROOT_FOR_CLIENT(pCD), pCD->pWsList->iconX,
  2832. pCD->pWsList->iconY);
  2833. }
  2834. if (pCD->maxConfig)
  2835. {
  2836. x = pCD->maxX;
  2837. y = pCD->maxY;
  2838. }
  2839. else
  2840. {
  2841. if(wmGD.positionIsFrame)
  2842. {
  2843. CalculateGravityOffset (pCD, &xoff, &yoff);
  2844. x = pCD->clientX - xoff;
  2845. y = pCD->clientY - yoff;
  2846. }
  2847. else
  2848. {
  2849. x = pCD->clientX;
  2850. y = pCD->clientY;
  2851. }
  2852. }
  2853. #ifndef UNMAP_ON_RESTART
  2854. if (pCD->clientState == MINIMIZED_STATE)
  2855. {
  2856. XUnmapWindow (DISPLAY, pCD->client);
  2857. }
  2858. #else
  2859. XUnmapWindow (DISPLAY, pCD->client);
  2860. #endif
  2861. XRemoveFromSaveSet (DISPLAY, pCD->client);
  2862. XReparentWindow (DISPLAY, pCD->client,
  2863. ROOT_FOR_CLIENT(pCD), x, y);
  2864. if (pCD->transientChildren)
  2865. {
  2866. DeFrameClient (pCD->transientChildren);
  2867. }
  2868. /*
  2869. * restore X border
  2870. */
  2871. windowChanges.x = x;
  2872. windowChanges.y = y;
  2873. windowChanges.border_width = pCD->xBorderWidth;
  2874. XConfigureWindow (DISPLAY, pCD->client, CWBorderWidth | CWX | CWY,
  2875. &windowChanges);
  2876. if (pCD->transientLeader)
  2877. {
  2878. pCD = pCD->transientSiblings;
  2879. }
  2880. else
  2881. {
  2882. pCD = NULL;
  2883. }
  2884. }
  2885. } /* END OF FUNCTION DeFrameClient */
  2886. /******************************<->*************************************
  2887. *
  2888. * F_Toggle_Front_Panel (args, pCD, event)
  2889. *
  2890. *
  2891. * Description:
  2892. * -----------
  2893. * This is the window manager function handler for toggling the
  2894. * front panel off and on.
  2895. ******************************<->***********************************/
  2896. Boolean
  2897. F_Toggle_Front_Panel (String args, ClientData *pCD, XEvent *event)
  2898. {
  2899. WmPanelistObject pPanelist;
  2900. if (pCD)
  2901. {
  2902. pPanelist = (WmPanelistObject) pCD->pSD->wPanelist;
  2903. }
  2904. else
  2905. {
  2906. pPanelist = (WmPanelistObject) ACTIVE_PSD->wPanelist;
  2907. }
  2908. pCD = NULL;
  2909. if (pPanelist)
  2910. {
  2911. (void) XFindContext (DISPLAY, XtWindow(O_Shell(pPanelist)),
  2912. wmGD.windowContextType, (caddr_t *)&pCD);
  2913. }
  2914. if (pCD)
  2915. {
  2916. if (pCD->clientState & MINIMIZED_STATE)
  2917. {
  2918. SetClientState (pCD, NORMAL_STATE,
  2919. GetFunctionTimestamp ((XButtonEvent *)event));
  2920. }
  2921. else
  2922. {
  2923. SetClientState (pCD, MINIMIZED_STATE,
  2924. GetFunctionTimestamp ((XButtonEvent *)event));
  2925. }
  2926. }
  2927. return(True);
  2928. } /* END OF FUNCTION F_Toggle_Front_Panel */
  2929. /******************************<->*************************************
  2930. *
  2931. * Boolean F_Version (String args, ClientData *pCD, XEvent *event)
  2932. *
  2933. * Description:
  2934. * -----------
  2935. * Invoke the help on version dialogue.
  2936. *
  2937. * Inputs:
  2938. * ------
  2939. * args - incoming values
  2940. * pCD - associated client data structure
  2941. * event - what triggered this call
  2942. *
  2943. * Outputs:
  2944. * -------
  2945. * Return - True if the call occurs; false otherwise.
  2946. *
  2947. * Comments:
  2948. * --------
  2949. *
  2950. ******************************<->***********************************/
  2951. Boolean
  2952. F_Version (String args, ClientData *pCD, XEvent *event)
  2953. {
  2954. WmPanelistObject pPanelist;
  2955. if (pCD)
  2956. {
  2957. pPanelist = (WmPanelistObject) pCD->pSD->wPanelist;
  2958. }
  2959. else
  2960. {
  2961. pPanelist = (WmPanelistObject) ACTIVE_PSD->wPanelist;
  2962. }
  2963. if (pPanelist)
  2964. {
  2965. WmDtHelpOnVersion (O_Shell (pPanelist));
  2966. }
  2967. return (True);
  2968. } /* END OF FUNCTION F_Version */
  2969. /******************************<->*************************************
  2970. *
  2971. * F_Send_Msg (args, pCD, event)
  2972. *
  2973. *
  2974. * Description:
  2975. * -----------
  2976. * This is the window manager function handler for sending a client
  2977. * message event to a client window.
  2978. *
  2979. *
  2980. * Inputs:
  2981. * ------
  2982. * args = (immediate value) message id
  2983. *
  2984. * pCD = pointer to the client data
  2985. *
  2986. * event = X event that invoked the function (key, button, or menu/NULL)
  2987. *
  2988. *
  2989. ******************************<->***********************************/
  2990. Boolean F_Send_Msg (String args, ClientData *pCD, XEvent *event)
  2991. {
  2992. int i;
  2993. if (pCD && pCD->mwmMessagesCount)
  2994. {
  2995. /*
  2996. * A message id must be made "active" by being included in the
  2997. * _MWM_MESSAGES property before the associated message can be sent.
  2998. */
  2999. for (i = 0; i < pCD->mwmMessagesCount; i++)
  3000. {
  3001. if (pCD->mwmMessages[i] == (long)args)
  3002. {
  3003. SendClientMsg (pCD->client, (long) wmGD.xa_MWM_MESSAGES,
  3004. (long)args, CurrentTime, NULL, 0);
  3005. return (True);
  3006. }
  3007. }
  3008. }
  3009. return (True);
  3010. } /* END OF FUNCTION F_Send_Msg */
  3011. /*************************************<->*************************************
  3012. *
  3013. * F_Separator (args, pCD, event)
  3014. *
  3015. *
  3016. * Description:
  3017. * -----------
  3018. * This is a placeholder function; it should never be called.
  3019. *
  3020. *************************************<->***********************************/
  3021. Boolean F_Separator (String args, ClientData *pCD, XEvent *event)
  3022. {
  3023. return (True);
  3024. } /* END OF FUNCTION F_Separator */
  3025. Boolean ForceRaiseWindow (ClientData *pcd)
  3026. {
  3027. #if 0
  3028. Window stackWindow;
  3029. WmScreenData *pSD = (ACTIVE_WS)->pSD;
  3030. #endif
  3031. XWindowChanges changes;
  3032. Boolean restack = False;
  3033. #if 0
  3034. if (pSD->clientList->type == MINIMIZED_STATE)
  3035. {
  3036. stackWindow = ICON_FRAME_WIN(pSD->clientList->pCD);
  3037. }
  3038. else
  3039. {
  3040. stackWindow = pSD->clientList->pCD->clientFrameWin;
  3041. }
  3042. #endif
  3043. /*
  3044. * Windows did not raise on regular f.raise because the raise was
  3045. * not relative to another window (methinks).
  3046. */
  3047. changes.stack_mode = Above;
  3048. XConfigureWindow (DISPLAY, pcd->clientFrameWin, CWStackMode,
  3049. &changes);
  3050. return (restack);
  3051. }
  3052. /*************************************<->*************************************
  3053. *
  3054. * F_Raise (args, pCD, event)
  3055. *
  3056. *
  3057. * Description:
  3058. * -----------
  3059. * This is the window manager function handler for topping the client window
  3060. * so that it is unobscured.
  3061. *
  3062. *************************************<->***********************************/
  3063. Boolean F_Raise (String args, ClientData *pCD, XEvent *event)
  3064. {
  3065. ClientListEntry *pEntry;
  3066. ClientListEntry *pNextEntry;
  3067. ClientListEntry *pStackEntry;
  3068. String string = args;
  3069. int flags = STACK_NORMAL;
  3070. WmWorkspaceData *pWS = ACTIVE_WS;
  3071. if (string)
  3072. {
  3073. /* process '-client' argument */
  3074. if (string[0] == '-')
  3075. {
  3076. string = &string[1];
  3077. string = (String) GetString ((unsigned char **) &string);
  3078. pStackEntry = NULL;
  3079. pNextEntry = ACTIVE_PSD->clientList;
  3080. while (pNextEntry &&
  3081. (pEntry = FindClientNameMatch (pNextEntry, True, string,
  3082. F_GROUP_ALL)))
  3083. {
  3084. pNextEntry = pEntry->nextSibling;
  3085. if (ClientInWorkspace (pWS, pEntry->pCD))
  3086. {
  3087. Do_Raise (pEntry->pCD, pStackEntry, STACK_NORMAL);
  3088. pStackEntry = pEntry;
  3089. }
  3090. }
  3091. }
  3092. /* process family stacking stuff */
  3093. else if (*string)
  3094. {
  3095. unsigned int slen, len, index;
  3096. slen = strlen(args) - 2; /* subtract '\n' and NULL */
  3097. for (index = 0; index < slen; string = &args[index+1])
  3098. {
  3099. if ((string = (String) GetString ((unsigned char **) &string)) == NULL)
  3100. break;
  3101. len = strlen(string);
  3102. if (!strcmp(string,"within"))
  3103. {
  3104. flags |= STACK_WITHIN_FAMILY;
  3105. }
  3106. else if (!strcmp(string,"freeFamily"))
  3107. {
  3108. flags |= STACK_FREE_FAMILY;
  3109. }
  3110. index += len;
  3111. }
  3112. if (ClientInWorkspace (pWS, pCD))
  3113. {
  3114. Do_Raise (pCD, (ClientListEntry *) NULL, flags);
  3115. }
  3116. }
  3117. }
  3118. else if (pCD)
  3119. {
  3120. if (ClientInWorkspace (pWS, pCD))
  3121. {
  3122. Do_Raise (pCD, (ClientListEntry *) NULL, STACK_NORMAL);
  3123. }
  3124. }
  3125. return (True);
  3126. } /* END OF FUNCTION F_Raise */
  3127. /*************************************<->*************************************
  3128. *
  3129. * Do_Raise (pCD, pStackEntry)
  3130. *
  3131. *
  3132. * Description:
  3133. * -----------
  3134. * This is the window manager function handler for topping the client window
  3135. * so that it is unobscured.
  3136. *
  3137. *
  3138. * Inputs:
  3139. * ------
  3140. * pCD = pointer to the client data of the window (or icon) to be raised.
  3141. *
  3142. * pStackEntry = pointer to client list entry for window that is to be
  3143. * above the raised window (if NULL window is raised to the top of the
  3144. * stack).
  3145. *
  3146. *************************************<->***********************************/
  3147. void Do_Raise (ClientData *pCD, ClientListEntry *pStackEntry, int flags)
  3148. {
  3149. Boolean restackTransients;
  3150. ClientData *pcdLeader;
  3151. WmWorkspaceData *pWS = ACTIVE_WS;
  3152. Boolean bLeaderRestacked;
  3153. if (pCD->pECD)
  3154. {
  3155. /*
  3156. * Window has been reparented into the front panel.
  3157. * Don't follow through on window stacking change.
  3158. */
  3159. return;
  3160. }
  3161. else if (ClientInWorkspace(pWS, pCD) &&
  3162. (!pStackEntry || ClientInWorkspace (pWS, pStackEntry->pCD)))
  3163. {
  3164. /*
  3165. * Both clients are in the current workspace. Set
  3166. * client indices so that the access macros work.
  3167. */
  3168. SetClientWsIndex (pCD);
  3169. if (pStackEntry)
  3170. {
  3171. SetClientWsIndex (pStackEntry->pCD);
  3172. }
  3173. }
  3174. else
  3175. {
  3176. /*
  3177. * One or both of the clients are not in the current workspace
  3178. * Do nothing.
  3179. */
  3180. return;
  3181. }
  3182. pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
  3183. if (wmGD.systemModalActive && (pcdLeader != wmGD.systemModalClient))
  3184. {
  3185. /*
  3186. * Don't raise the window above the system modal window.
  3187. */
  3188. }
  3189. else if ((pcdLeader->clientState == MINIMIZED_STATE) &&
  3190. !P_ICON_BOX(pcdLeader))
  3191. {
  3192. /*
  3193. * If a dirtyStackEntry exists, return it to its original place
  3194. * in the stack (for all stacking types)
  3195. */
  3196. if (dirtyStackEntry)
  3197. {
  3198. if (dirtyStackEntry->transientChildren ||
  3199. dirtyStackEntry->transientLeader)
  3200. RestackTransients (dirtyStackEntry);
  3201. dirtyStackEntry = NULL;
  3202. dirtyLeader = NULL;
  3203. }
  3204. /*
  3205. * Only restack the icon if it is not currently raised.
  3206. */
  3207. if (pStackEntry)
  3208. {
  3209. if (pStackEntry->nextSibling != &pcdLeader->iconEntry)
  3210. {
  3211. StackWindow (pWS, &pcdLeader->iconEntry, False /*below*/,
  3212. pStackEntry);
  3213. MoveEntryInList (pWS, &pcdLeader->iconEntry, False /*below*/,
  3214. pStackEntry);
  3215. }
  3216. }
  3217. else
  3218. {
  3219. if (ACTIVE_PSD->clientList != &pcdLeader->iconEntry)
  3220. {
  3221. StackWindow (pWS, &pcdLeader->iconEntry,
  3222. True /*on top*/, (ClientListEntry *) NULL);
  3223. MoveEntryInList (pWS, &pcdLeader->iconEntry,
  3224. True /*on top*/, (ClientListEntry *) NULL);
  3225. }
  3226. }
  3227. }
  3228. else /* NORMAL_STATE, MAXIMIZED_STATE, adoption */
  3229. {
  3230. /*
  3231. * Handle restacking of primary/secondary windows
  3232. * within the transient window tree. Don't raise this
  3233. * window above any modal transients.
  3234. */
  3235. bLeaderRestacked = False;
  3236. if ((pcdLeader->transientChildren) &&
  3237. (!pCD->secondariesOnTop) &&
  3238. (!wmGD.bSuspendSecondaryRestack) &&
  3239. (!IS_APP_MODALIZED(pCD)))
  3240. {
  3241. if (pCD != pcdLeader)
  3242. {
  3243. /*
  3244. * This is not the transient leader, make sure
  3245. * the transient leader isn't on top.
  3246. * (Brute force solution)
  3247. */
  3248. bLeaderRestacked = NormalizeTransientTreeStacking (pcdLeader);
  3249. if (pCD->transientChildren)
  3250. {
  3251. /*
  3252. * This isn't the overall leader of the transient
  3253. * tree, but it does have transient's of its own.
  3254. * Move it to the top of its own transient sub-tree.
  3255. */
  3256. bLeaderRestacked |= BumpPrimaryToTop (pCD);
  3257. }
  3258. }
  3259. else
  3260. {
  3261. /*
  3262. * This is the transient leader, move it to the
  3263. * top.
  3264. */
  3265. bLeaderRestacked = BumpPrimaryToTop (pcdLeader);
  3266. }
  3267. }
  3268. /*
  3269. * If this is a transient window then put it on top of its
  3270. * sibling transient windows.
  3271. */
  3272. restackTransients = False;
  3273. /*
  3274. * Fix for 5325 - The following code has been reorganized to cause the
  3275. * action of F_Raise to match the current documentation.
  3276. * The new algorithm is as follows:
  3277. *
  3278. * if (dirtyStackEntry)
  3279. * restore dirty tree
  3280. * if (not withinFamily)
  3281. * bring window group to the top of global stack
  3282. * if (freeFamily)
  3283. * raise the requested window to top of family
  3284. * else
  3285. * raise requested window to top of siblings
  3286. * if (need to restack windows)
  3287. * restack windows
  3288. * return
  3289. */
  3290. /*
  3291. * If a dirtyStackEntry exists, return it to its original place
  3292. * in the stack (for all stacking types)
  3293. */
  3294. if (dirtyStackEntry)
  3295. {
  3296. /*
  3297. * Check to make sure that the dirty pCD has either transient
  3298. * children or a transient leader. If not, do not restore
  3299. * the transients.
  3300. */
  3301. if (dirtyStackEntry->transientChildren ||
  3302. dirtyStackEntry->transientLeader)
  3303. RestackTransients (dirtyStackEntry);
  3304. dirtyStackEntry = NULL;
  3305. dirtyLeader = NULL;
  3306. }
  3307. /*
  3308. * If the flags do not indicate "within", raise the window family
  3309. * to the top of the window stack. If the window is the primary,
  3310. * raise it to the top regardless of the flags.
  3311. */
  3312. if (!pCD->transientLeader || !(flags & STACK_WITHIN_FAMILY))
  3313. {
  3314. if (pStackEntry)
  3315. {
  3316. if (pStackEntry->nextSibling != &pcdLeader->clientEntry)
  3317. {
  3318. StackWindow (pWS, &pcdLeader->clientEntry,
  3319. False /*below*/, pStackEntry);
  3320. MoveEntryInList (pWS, &pcdLeader->clientEntry,
  3321. False /*below*/, pStackEntry);
  3322. }
  3323. }
  3324. else
  3325. {
  3326. if (ACTIVE_PSD->clientList != &pcdLeader->clientEntry)
  3327. {
  3328. StackWindow (pWS, &pcdLeader->clientEntry,
  3329. True /*on top*/, (ClientListEntry *) NULL);
  3330. MoveEntryInList (pWS, &pcdLeader->clientEntry,
  3331. True /*on top*/, (ClientListEntry *) NULL);
  3332. }
  3333. }
  3334. }
  3335. /*
  3336. * If freeFamily stacking is requested, check to make sure that
  3337. * the window has either a transientChild or Leader. This will
  3338. * guarantee that windows that form their own family are not
  3339. * labelled as dirty (what's to dirty it up?). If it has either,
  3340. * raise the window to the top of the family stack.
  3341. */
  3342. if ((flags & STACK_FREE_FAMILY) &&
  3343. (pCD->transientLeader || pCD->transientChildren))
  3344. {
  3345. dirtyStackEntry = pCD;
  3346. dirtyLeader = pcdLeader;
  3347. restackTransients = ForceRaiseWindow (pCD);
  3348. }
  3349. /*
  3350. * If withinFamily stacking is requested, put the current transient
  3351. * on top of its sibling transient windows.
  3352. */
  3353. else
  3354. {
  3355. restackTransients = PutTransientOnTop (pCD);
  3356. }
  3357. /* At this point, if doing a regular f.raise the window family has
  3358. * already been brought to the top of the stack, so nothing further
  3359. * needs to be done for it.
  3360. */
  3361. /* Restack the transients if needed */
  3362. if ((restackTransients) || (bLeaderRestacked))
  3363. {
  3364. RestackTransients (pCD);
  3365. }
  3366. }
  3367. } /* END OF FUNCTION Do_Raise */
  3368. /*************************************<->*************************************
  3369. *
  3370. * F_Raise_Lower (args, pCD, event)
  3371. *
  3372. *
  3373. * Description:
  3374. * -----------
  3375. * This window manager function tops an obscured window or icon and bottoms
  3376. * a window or icon that is on top of the window stack.
  3377. *
  3378. *************************************<->***********************************/
  3379. Boolean F_Raise_Lower (String args, ClientData *pCD, XEvent *event)
  3380. {
  3381. ClientData *pcdLeader;
  3382. if (pCD)
  3383. {
  3384. pcdLeader = (pCD->transientLeader) ?
  3385. FindTransientTreeLeader (pCD) : pCD;
  3386. /*
  3387. * Treat a raise/lower on a window in a transient tree as if it is
  3388. * a raise/lower for the whole tree.
  3389. */
  3390. if (CheckIfClientObscuredByAny (pcdLeader))
  3391. {
  3392. /*
  3393. * The window is obscured by another window, raise the window.
  3394. */
  3395. F_Raise (NULL, pCD, (XEvent *)NULL);
  3396. }
  3397. else if (CheckIfClientObscuringAny (pcdLeader) &&
  3398. !(wmGD.systemModalActive &&
  3399. (pcdLeader == wmGD.systemModalClient)))
  3400. {
  3401. /*
  3402. * The window is obscuring another window and is
  3403. * not system modal, lower the window.
  3404. */
  3405. F_Lower (NULL, pcdLeader, (XEvent *)NULL);
  3406. if ((pcdLeader->secondariesOnTop == False) &&
  3407. (pCD->transientLeader != NULL) &&
  3408. (!IS_APP_MODALIZED(pcdLeader)))
  3409. {
  3410. /* Push transient below primary */
  3411. (void) BumpPrimaryToTop (pcdLeader);
  3412. RestackTransients (pcdLeader);
  3413. }
  3414. }
  3415. else if ((pcdLeader->secondariesOnTop == False) &&
  3416. (pcdLeader->transientChildren != NULL) &&
  3417. (!wmGD.systemModalActive) &&
  3418. (!IS_APP_MODALIZED(pcdLeader)))
  3419. {
  3420. if (LeaderOnTop(pcdLeader))
  3421. {
  3422. /* Push primary below transient */
  3423. (void) BumpPrimaryToBottom (pcdLeader);
  3424. RestackTransients (pcdLeader);
  3425. }
  3426. else
  3427. {
  3428. F_Raise (NULL, pCD, (XEvent *)NULL);
  3429. /* Push transient below primary */
  3430. (void) BumpPrimaryToTop (pcdLeader);
  3431. RestackTransients (pcdLeader);
  3432. }
  3433. }
  3434. }
  3435. return (True);
  3436. } /* END OF FUNCTION F_Raise_Lower */
  3437. /*************************************<->*************************************
  3438. *
  3439. * F_Refresh_Win (args, pCD, event)
  3440. *
  3441. *
  3442. * Description:
  3443. * -----------
  3444. * This is the window manager function handler for causing a client window
  3445. * to redisplay itself.
  3446. *
  3447. *************************************<->***********************************/
  3448. Boolean F_Refresh_Win (String args, ClientData *pCD, XEvent *event)
  3449. {
  3450. Window win;
  3451. unsigned int w, h;
  3452. if (pCD && ((pCD->clientState == NORMAL_STATE) ||
  3453. (pCD->clientState == MAXIMIZED_STATE)))
  3454. {
  3455. if (pCD->clientState == NORMAL_STATE)
  3456. {
  3457. w = (unsigned int) pCD->clientWidth;
  3458. h = (unsigned int) pCD->clientHeight;
  3459. }
  3460. else
  3461. {
  3462. w = (unsigned int) pCD->maxWidth;
  3463. h = (unsigned int) pCD->maxHeight;
  3464. }
  3465. if (wmGD.refreshByClearing)
  3466. {
  3467. RefreshByClearing (pCD->clientFrameWin);
  3468. }
  3469. else
  3470. {
  3471. /* default background_pixmap is None */
  3472. win = XCreateWindow (DISPLAY,
  3473. pCD->clientBaseWin,
  3474. pCD->matteWidth,
  3475. pCD->matteWidth,
  3476. w, h,
  3477. 0,
  3478. 0,
  3479. InputOutput,
  3480. CopyFromParent,
  3481. 0,
  3482. (XSetWindowAttributes *)NULL);
  3483. XMapWindow (DISPLAY, win);
  3484. XDestroyWindow (DISPLAY, win);
  3485. }
  3486. XFlush (DISPLAY);
  3487. }
  3488. return (True);
  3489. } /* END OF FUNCTION F_Refresh_Win */
  3490. /*************************************<->*************************************
  3491. *
  3492. * F_Set_Behavior (args, pCD, event)
  3493. *
  3494. *
  3495. * Description:
  3496. * -----------
  3497. * This function is used to switch the window manager configuration between
  3498. * the built-in configuration (for CXI behavior) and the user's custom
  3499. * configuration.
  3500. *
  3501. *************************************<->***********************************/
  3502. Boolean F_Set_Behavior (String args, ClientData *pCD, XEvent *event)
  3503. {
  3504. /*
  3505. * Go system modal in starting to do the set behavior.
  3506. */
  3507. /* !!! grab the server and the pointer !!! */
  3508. /*
  3509. * Confirm that a set_behavior should be done.
  3510. * Execute restart if so.
  3511. */
  3512. if (wmGD.showFeedback & WM_SHOW_FB_BEHAVIOR)
  3513. {
  3514. ConfirmAction (ACTIVE_PSD, (wmGD.useStandardBehavior) ?
  3515. CUSTOM_BEHAVIOR_ACTION : DEFAULT_BEHAVIOR_ACTION);
  3516. }
  3517. else
  3518. {
  3519. RestartWm ((long) ((wmGD.useStandardBehavior) ?
  3520. MWM_INFO_STARTUP_CUSTOM : MWM_INFO_STARTUP_STANDARD));
  3521. }
  3522. return (False);
  3523. } /* END OF FUNCTION F_Set_Behavior */
  3524. /*************************************<->*************************************
  3525. *
  3526. * Do_Set_Behavior (dummy)
  3527. *
  3528. *
  3529. * Description:
  3530. * -----------
  3531. * Callback to do the f.set_behavior function.
  3532. *
  3533. *************************************<->***********************************/
  3534. void Do_Set_Behavior (Boolean dummy)
  3535. {
  3536. RestartWm ((long) ((wmGD.useStandardBehavior) ?
  3537. MWM_INFO_STARTUP_CUSTOM : MWM_INFO_STARTUP_STANDARD));
  3538. } /* END OF FUNCTION Do_Set_Behavior */
  3539. /*************************************<->*************************************
  3540. *
  3541. * F_Set_Context (args, pCD, event)
  3542. *
  3543. *
  3544. * Description:
  3545. * -----------
  3546. * This function is used to set a client context for subsequent
  3547. * WM_REQUESTs
  3548. *
  3549. *************************************<->***********************************/
  3550. Boolean F_Set_Context (String args, ClientData *pCD, XEvent *event)
  3551. {
  3552. wmGD.requestContextWin = (Window) args;
  3553. return (True);
  3554. } /* END OF FUNCTION F_Set_Context */
  3555. /*************************************<->*************************************
  3556. *
  3557. * F_Title (args, pCD, event)
  3558. *
  3559. *
  3560. * Description:
  3561. * -----------
  3562. * This is a placeholder function; it should never be called.
  3563. *
  3564. *************************************<->***********************************/
  3565. Boolean F_Title (String args, ClientData *pCD, XEvent *event)
  3566. {
  3567. return (True);
  3568. } /* END OF FUNCTION F_Title */
  3569. /******************************<->*************************************
  3570. *
  3571. * F_Screen (args, pCD, event)
  3572. *
  3573. *
  3574. * Description:
  3575. * -----------
  3576. * This is the window manager function handler for warping to screens
  3577. *
  3578. *
  3579. * Inputs:
  3580. * ------
  3581. * args = (immediate value) window type flags
  3582. *
  3583. * pCD = pointer to the client data
  3584. *
  3585. * event = X event that invoked the function (key, button, or menu/NULL)
  3586. *
  3587. * NOTE: May want to consider tracking changes in screen because in
  3588. * managing a new window (ie. in ManageWindow()).
  3589. *
  3590. * Outputs:
  3591. * -------
  3592. * RETURN = if True then further button binding/function processing can
  3593. * be done for the event that caused this function to be called.
  3594. *
  3595. *************************************<->***********************************/
  3596. Boolean F_Screen (String args, ClientData *pCD, XEvent *event)
  3597. {
  3598. Window dumwin;
  3599. int x, y, dumint;
  3600. unsigned int dummask;
  3601. WmScreenData *newscr = NULL;
  3602. int scr, inc;
  3603. static int PreviousScreen = -1;
  3604. char pch[80];
  3605. if (PreviousScreen == -1)
  3606. {
  3607. PreviousScreen = DefaultScreen(DISPLAY);
  3608. }
  3609. if (strcmp (args, "next") == 0)
  3610. {
  3611. scr = ACTIVE_PSD->screen + 1;
  3612. inc = 1;
  3613. }
  3614. else if (strcmp (args, "prev") == 0)
  3615. {
  3616. scr = ACTIVE_PSD->screen - 1;
  3617. inc = -1;
  3618. }
  3619. else if (strcmp (args, "back") == 0)
  3620. {
  3621. scr = PreviousScreen;
  3622. inc = 0;
  3623. }
  3624. else
  3625. {
  3626. scr = atoi (args);
  3627. inc = 0;
  3628. }
  3629. while (!newscr) {
  3630. /* wrap around */
  3631. if (scr < 0)
  3632. scr = wmGD.numScreens - 1;
  3633. else if (scr >= wmGD.numScreens)
  3634. scr = 0;
  3635. newscr = &(wmGD.Screens[scr]);
  3636. if (!wmGD.Screens[scr].managed) { /* make sure screen is managed */
  3637. if (inc) { /* walk around the list */
  3638. scr += inc;
  3639. continue;
  3640. }
  3641. sprintf(pch,
  3642. "Unable to warp to unmanaged screen %d\n", scr);
  3643. Warning (&pch[0]);
  3644. XBell (DISPLAY, 0);
  3645. return (False);
  3646. }
  3647. }
  3648. if (ACTIVE_PSD->screen == scr) return (False); /* already on that screen */
  3649. PreviousScreen = ACTIVE_PSD->screen;
  3650. XQueryPointer (DISPLAY, ACTIVE_ROOT, &dumwin, &dumwin, &x, &y,
  3651. &dumint, &dumint, &dummask);
  3652. XWarpPointer (DISPLAY, None, newscr->rootWindow, 0, 0, 0, 0, x, y);
  3653. if (newscr && (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
  3654. {
  3655. /*
  3656. * Set the ACTIVE_PSD to the new screen so that Do_Focus_Key can
  3657. * uses the new screen instead of the old screen. Then call
  3658. * Do_Focus_Key with a NULL pCD to find a reasonable client to
  3659. * set focus to.
  3660. */
  3661. SetActiveScreen (newscr);
  3662. Do_Focus_Key (NULL, GetFunctionTimestamp ((XButtonEvent *)event),
  3663. ALWAYS_SET_FOCUS);
  3664. }
  3665. return (False);
  3666. }
  3667. /*************************************<->*************************************
  3668. *
  3669. * GetFunctionTimestamp (pEvent)
  3670. *
  3671. *
  3672. * Description:
  3673. * -----------
  3674. * This function is used to extract a timestamp from a key or button event.
  3675. * If the event passed in is not a key or button event then a timestamp
  3676. * is generated.
  3677. *
  3678. *
  3679. * Inputs:
  3680. * ------
  3681. * event = pointer to an X event
  3682. *
  3683. *
  3684. * Outputs:
  3685. * -------
  3686. * RETURN = a timestamp
  3687. *
  3688. *************************************<->***********************************/
  3689. Time GetFunctionTimestamp (XButtonEvent *pEvent)
  3690. {
  3691. Time time;
  3692. if (pEvent &&
  3693. (((pEvent->type == ButtonPress) || (pEvent->type == ButtonRelease)) ||
  3694. ((pEvent->type == KeyPress) || (pEvent->type == KeyRelease))))
  3695. {
  3696. time = pEvent->time;
  3697. }
  3698. else
  3699. {
  3700. time = GetTimestamp ();
  3701. }
  3702. return (time);
  3703. } /* END OF FUNCTION GetFunctionTimestamp */
  3704. /*
  3705. ** name the event mask we need for a grab in order to find the matching
  3706. ** event for an event; right now handle only button-presses
  3707. */
  3708. static unsigned int GetEventInverseMask(XEvent *event)
  3709. {
  3710. if ((XEvent*)NULL == event)
  3711. return 0;
  3712. if (ButtonPress == event->type)
  3713. return ButtonReleaseMask; /* detail ? */
  3714. /*
  3715. expansion further here
  3716. */
  3717. else
  3718. return 0;
  3719. }
  3720. /*************************************<->*************************************
  3721. *
  3722. * ClearDirtyStackEntry (pCD)
  3723. *
  3724. *
  3725. * Description:
  3726. * -----------
  3727. * This function is used to clear the static dirtyStackEntry structure and
  3728. * the dirtyLeader static variable when a pCD is destroyed. This
  3729. * guarantees that freed memory will not be accessed.
  3730. *
  3731. *
  3732. * Inputs:
  3733. * ------
  3734. * pCD = pointer to clientData being freed
  3735. *
  3736. *
  3737. * Outputs:
  3738. * -------
  3739. * RETURN = void
  3740. *
  3741. *************************************<->***********************************/
  3742. void ClearDirtyStackEntry (ClientData *pCD)
  3743. {
  3744. if (pCD == dirtyStackEntry)
  3745. {
  3746. dirtyStackEntry = NULL;
  3747. dirtyLeader = NULL;
  3748. }
  3749. }
  3750. #if defined(DEBUG)
  3751. /***********************<->*************************************
  3752. *
  3753. * F_ZZ_Debug (args, pCD, event)
  3754. *
  3755. *
  3756. * Description:
  3757. * -----------
  3758. * This is the window manager debug (multi) function
  3759. *
  3760. *
  3761. * Inputs:
  3762. * ------
  3763. * args = arguments
  3764. *
  3765. * pCD = pointer to the ClientData for the whole front panel
  3766. *
  3767. * event = X event that invoked the function (key, button, or menu/NULL)
  3768. *
  3769. *
  3770. * Outputs:
  3771. * -------
  3772. * RETURN = if True then further button binding/function processing can
  3773. * be done for the event that caused this function to be called.
  3774. *
  3775. * Comments:
  3776. * -------
  3777. * Argument 1 determines the debug function to execute:
  3778. *
  3779. * Valid arguments:
  3780. *
  3781. * "color_server_info" - dump out color server info
  3782. *
  3783. ******************************<->***********************************/
  3784. Boolean
  3785. F_ZZ_Debug (String subFcn, ClientData *pCD, XEvent *event)
  3786. {
  3787. /* Only do something is sub function is specified */
  3788. if (subFcn)
  3789. {
  3790. if (!(strcmp(subFcn, "dump_resources")))
  3791. {
  3792. int scr;
  3793. char szRes[80];
  3794. for (scr=0; scr<wmGD.numScreens; scr++)
  3795. {
  3796. sprintf (szRes, "/tmp/dtwm.resources.%d", scr);
  3797. XrmPutFileDatabase(XtScreenDatabase(
  3798. XScreenOfDisplay(DISPLAY, scr)),
  3799. szRes);
  3800. }
  3801. }
  3802. }
  3803. return (True);
  3804. }
  3805. #endif /* DEBUG */
  3806. /*************************************<->*************************************
  3807. *
  3808. * F_Next_Workspace (args, pCD, event)
  3809. *
  3810. *
  3811. * Description:
  3812. * -----------
  3813. * This function switches to the next workspace in the list
  3814. *
  3815. *************************************<->***********************************/
  3816. Boolean F_Next_Workspace (String args, ClientData *pCD, XEvent *event)
  3817. {
  3818. WmScreenData *pSD = ACTIVE_PSD;
  3819. int iwsx;
  3820. for (iwsx = 0; iwsx < pSD->numWorkspaces; iwsx++)
  3821. {
  3822. if (pSD->pWS[iwsx].id == pSD->pActiveWS->id)
  3823. {
  3824. iwsx++;
  3825. break;
  3826. }
  3827. }
  3828. /* check bounds and wrap */
  3829. if (iwsx >= pSD->numWorkspaces)
  3830. iwsx = 0;
  3831. ChangeToWorkspace (&pSD->pWS[iwsx]);
  3832. return (False);
  3833. } /* END OF FUNCTION F_Next_Workspace */
  3834. /*************************************<->*************************************
  3835. *
  3836. * F_Prev_Workspace (args, pCD, event)
  3837. *
  3838. *
  3839. * Description:
  3840. * -----------
  3841. * This function switches to the previous workspace in the list
  3842. *
  3843. *************************************<->***********************************/
  3844. Boolean F_Prev_Workspace (String args, ClientData *pCD, XEvent *event)
  3845. {
  3846. WmScreenData *pSD = ACTIVE_PSD;
  3847. int iwsx;
  3848. for (iwsx = 0; iwsx < pSD->numWorkspaces; iwsx++)
  3849. {
  3850. if (pSD->pWS[iwsx].id == pSD->pActiveWS->id)
  3851. {
  3852. iwsx--;
  3853. break;
  3854. }
  3855. }
  3856. /* check bounds and wrap */
  3857. if (iwsx < 0)
  3858. iwsx = pSD->numWorkspaces - 1;
  3859. ChangeToWorkspace (&pSD->pWS[iwsx]);
  3860. return (False);
  3861. } /* END OF FUNCTION F_Prev_Workspace */
  3862. /*************************************<->*************************************
  3863. *
  3864. * F_Workspace_Presence (args, pCD, event)
  3865. *
  3866. *
  3867. * Description:
  3868. * -----------
  3869. * This function pops up the workspace presence dialog box
  3870. *
  3871. *************************************<->***********************************/
  3872. Boolean F_Workspace_Presence (String args, ClientData *pCD, XEvent *event)
  3873. {
  3874. Context wsContext = (Context)NULL;
  3875. if (pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS))
  3876. {
  3877. if (pCD->clientState == NORMAL_STATE)
  3878. {
  3879. wsContext = F_CONTEXT_NORMAL;
  3880. }
  3881. else if (pCD->clientState == MAXIMIZED_STATE)
  3882. {
  3883. wsContext = F_CONTEXT_MAXIMIZE;
  3884. }
  3885. else
  3886. {
  3887. wsContext = F_CONTEXT_ICON;
  3888. /* return (False); */
  3889. }
  3890. ShowPresenceBox (pCD, wsContext);
  3891. }
  3892. return (False);
  3893. } /* END OF FUNCTION F_Workspace_Presence */
  3894. /**
  3895. * @brief This function pops up the instant title dialog.
  3896. *
  3897. * @param args
  3898. * @param pCD
  3899. * @param event
  3900. *
  3901. * @return False
  3902. */
  3903. Boolean F_Rename (String args, ClientData *pCD, XEvent *event)
  3904. {
  3905. if (pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS))
  3906. {
  3907. InstantTitleShowDialog (pCD);
  3908. }
  3909. return False;
  3910. }
  3911. #ifdef DEBUG
  3912. void
  3913. DumpWindowList ()
  3914. {
  3915. WmScreenData *pSD = (ACTIVE_WS)->pSD;
  3916. ClientListEntry *pCLE;
  3917. fprintf (stdout, "Window stacking (bottom to top)\n");
  3918. pCLE = pSD->lastClient;
  3919. while (pCLE)
  3920. {
  3921. if (ClientInWorkspace (ACTIVE_WS, pCLE->pCD))
  3922. fprintf (stdout, "* ");
  3923. else
  3924. fprintf (stdout, " ");
  3925. fprintf (stdout, "%08lx\t%s\n",
  3926. pCLE->pCD->client,
  3927. pCLE->pCD->clientName);
  3928. pCLE = pCLE->prevSibling;
  3929. }
  3930. }
  3931. #endif /* DEBUG */