2
0

WmWrkspace.c 80 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871
  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 1987,1988,1989,1990,1992,1993,1994 HEWLETT-PACKARD COMPANY
  25. * (c) Copyright 1993, 1994 International Business Machines Corp.
  26. * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  27. * (c) Copyright 1993, 1994 Novell, Inc.
  28. * ALL RIGHTS RESERVED
  29. */
  30. /*
  31. * Included Files:
  32. */
  33. #include "WmGlobal.h"
  34. #include "WmHelp.h"
  35. #include "WmResNames.h"
  36. #include "WmIPlace.h"
  37. #include "WmInitWs.h"
  38. #include <X11/Xutil.h>
  39. #include "WmICCC.h"
  40. #include <Xm/Xm.h>
  41. #include <Xm/AtomMgr.h>
  42. #include <Dt/DtP.h>
  43. #include <Dt/WsmM.h>
  44. #include <stdio.h>
  45. #include "WmPanelP.h"
  46. #include "WmIPC.h" /* must be after DtP.h */
  47. #include "WmPresence.h"
  48. /* local macros */
  49. #ifndef MIN
  50. #define MIN(a,b) ((a)<=(b)?(a):(b))
  51. #endif
  52. #ifndef MAX
  53. #define MAX(a,b) ((a)>=(b)?(a):(b))
  54. #endif
  55. /* internally defined functions */
  56. #include "WmWrkspace.h"
  57. /******** Static Function Declarations ********/
  58. static void InsureUniqueWorkspaceHints(
  59. ClientData *pCD) ;
  60. /******** End Static Function Declarations ********/
  61. /* FindDtSessionMatch () put in WmResParse.h */
  62. /* external functions */
  63. #include "WmBackdrop.h"
  64. #include "WmError.h"
  65. #include "WmFunction.h"
  66. #include "WmIDecor.h"
  67. #include "WmIconBox.h"
  68. #include "WmMenu.h"
  69. #include "WmProperty.h"
  70. #include "WmResParse.h"
  71. #include "WmWinInfo.h"
  72. #include "WmWinList.h"
  73. #include "WmWinState.h"
  74. #include "WmXSMP.h"
  75. /*
  76. * Global Variables:
  77. */
  78. /* a dynamically allocated list of workspaces used
  79. * by F_AddToAllWorkspaces
  80. */
  81. static int numResIDs = 0;
  82. static WorkspaceID *pResIDs = NULL;
  83. /*************************************<->*************************************
  84. *
  85. * ChangeToWorkspace (pNewWS)
  86. *
  87. *
  88. * Description:
  89. * -----------
  90. * This function changes to a new workspace.
  91. *
  92. * Inputs:
  93. * ------
  94. * pNewWS = pointer to workspace data
  95. *
  96. *
  97. *************************************<->***********************************/
  98. void
  99. ChangeToWorkspace(
  100. WmWorkspaceData *pNewWS )
  101. {
  102. ClientData *pCD;
  103. int i;
  104. WmScreenData *pSD = pNewWS->pSD;
  105. ClientData *pWsPCD;
  106. Context wsContext = F_CONTEXT_NONE;
  107. if (pNewWS == pSD->pActiveWS)
  108. return; /* already there */
  109. pSD->pLastWS = pSD->pActiveWS;
  110. /*
  111. * Go through client list of old workspace and hide windows
  112. * that shouldn't appear in new workspace.
  113. */
  114. if (pSD->presence.shellW &&
  115. pSD->presence.onScreen &&
  116. pSD->presence.contextForClient == F_CONTEXT_ICON)
  117. {
  118. pWsPCD = pSD->presence.pCDforClient;
  119. wsContext = pSD->presence.contextForClient;
  120. HidePresenceBox (pSD, False);
  121. }
  122. for (i = 0; i < pSD->pActiveWS->numClients; i++)
  123. {
  124. pCD = pSD->pActiveWS->ppClients[i];
  125. if (!ClientInWorkspace (pNewWS, pCD))
  126. {
  127. SetClientWsIndex(pCD);
  128. SetClientState (pCD, pCD->clientState | UNSEEN_STATE,
  129. CurrentTime);
  130. }
  131. }
  132. /*
  133. * Hide active icon text label
  134. */
  135. if ((pSD->iconDecoration & ICON_ACTIVE_LABEL_PART) &&
  136. wmGD.activeIconTextDisplayed)
  137. {
  138. HideActiveIconText(pSD);
  139. }
  140. /*
  141. * Unmap old icon box
  142. */
  143. if (pSD->useIconBox)
  144. {
  145. UnmapIconBoxes (pSD->pLastWS);
  146. }
  147. /*
  148. * Set new active workspace
  149. */
  150. pSD->pActiveWS = pNewWS;
  151. ChangeBackdrop (pNewWS);
  152. /*
  153. * Go through client list of new workspace and show windows
  154. * that should appear.
  155. */
  156. for (i = 0; i < pNewWS->numClients; i++)
  157. {
  158. pCD = pNewWS->ppClients[i];
  159. SetClientWsIndex(pCD);
  160. if (pCD->clientState & UNSEEN_STATE)
  161. {
  162. SetClientState (pCD,
  163. (pCD->clientState & ~UNSEEN_STATE), CurrentTime);
  164. }
  165. if ((pCD->clientState == MINIMIZED_STATE) &&
  166. ((!pCD->pSD->useIconBox) ||
  167. (!P_ICON_BOX(pCD))))
  168. {
  169. XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
  170. ICON_X(pCD), ICON_Y(pCD));
  171. }
  172. if (pCD->iconWindow)
  173. {
  174. unsigned int xOffset, yOffset;
  175. /*
  176. * Adjust for icons in the box
  177. */
  178. if (pNewWS->pIconBox)
  179. {
  180. xOffset = IB_MARGIN_WIDTH;
  181. yOffset = IB_MARGIN_HEIGHT;
  182. }
  183. else
  184. {
  185. xOffset = 0;
  186. yOffset = 0;
  187. }
  188. /*
  189. * reparent icon window to frame in this workspace
  190. */
  191. if ((ICON_DECORATION(pCD) & ICON_IMAGE_PART) &&
  192. (pCD->iconWindow))
  193. {
  194. ReparentIconWindow (pCD, xOffset, yOffset);
  195. }
  196. }
  197. }
  198. if ( (wsContext == F_CONTEXT_ICON &&
  199. ClientInWorkspace (ACTIVE_WS, pWsPCD)) ||
  200. (pSD->presence.shellW &&
  201. ! pSD->presence.userDismissed &&
  202. ClientInWorkspace (ACTIVE_WS, pSD->presence.pCDforClient) &&
  203. pSD->presence.contextForClient == F_CONTEXT_ICON))
  204. {
  205. ShowPresenceBox(pSD->presence.pCDforClient, F_CONTEXT_ICON);
  206. }
  207. SetCurrentWorkspaceProperty (pSD);
  208. /* send workspace change broadcast message */
  209. dtSendWorkspaceModifyNotification(pSD, (Atom) pNewWS->id,
  210. DtWSM_REASON_CURRENT);
  211. } /* END OF FUNCTION ChangeToWorkspace */
  212. /******************************<->*************************************
  213. *
  214. * ChangeWorkspaceTitle (pWS, pchTitle)
  215. *
  216. * Description:
  217. * -----------
  218. * Set the title for a workspace.
  219. *
  220. * Inputs:
  221. * ------
  222. * pWS = pointer to workspace data
  223. * pchTitle = new title to assign to this workspace
  224. *
  225. * Outputs:
  226. * -------
  227. * none
  228. *
  229. * Comments:
  230. * --------
  231. *
  232. ******************************<->***********************************/
  233. void
  234. ChangeWorkspaceTitle(
  235. WmWorkspaceData *pWS,
  236. char * pchTitle)
  237. {
  238. XmString xmstr;
  239. /*
  240. * Convert string to XmString
  241. */
  242. xmstr = XmStringCreateLocalized (pchTitle);
  243. /*
  244. * Validate title ?
  245. */
  246. /*
  247. * Replace title in workspace data
  248. */
  249. XmStringFree (pWS->title);
  250. pWS->title = xmstr;
  251. /*
  252. * Save changes to resource database
  253. */
  254. SaveWorkspaceResources (pWS, (WM_RES_WORKSPACE_TITLE));
  255. /*
  256. * Replace old workspace in info property
  257. */
  258. SetWorkspaceInfoProperty (pWS);
  259. XFlush (DISPLAY);
  260. /*
  261. * Inform the world of the new workspace title
  262. */
  263. dtSendWorkspaceModifyNotification(pWS->pSD, pWS->id, DtWSM_REASON_TITLE);
  264. } /* END OF FUNCTION ChangeWorkspaceTitle */
  265. /*************************************<->*************************************
  266. *
  267. * UpdateWorkspacePresenceProperty (pCD)
  268. *
  269. *
  270. * Description:
  271. * -----------
  272. * This function updates the _DT_WORKSPACE_PRESENCE property for a
  273. * client window
  274. *
  275. * Inputs:
  276. * ------
  277. * pCD = pointer to client data
  278. *
  279. *
  280. *************************************<->***********************************/
  281. void
  282. UpdateWorkspacePresenceProperty(
  283. ClientData *pCD )
  284. {
  285. static Atom *pPresence = NULL;
  286. static unsigned long cPresence = 0;
  287. unsigned long i;
  288. if (wmGD.useStandardBehavior)
  289. {
  290. /*
  291. * Don't change any workspace properties in standard behavior
  292. * mode.
  293. */
  294. return;
  295. }
  296. if (!pPresence)
  297. {
  298. /* allocate initial list */
  299. if (!(pPresence = (Atom *)
  300. XtMalloc (pCD->pSD->numWorkspaces * sizeof(Atom))))
  301. {
  302. Warning (((char *)GETMESSAGE(76, 1, "Insufficient memory for workspace presence property")));
  303. }
  304. else
  305. {
  306. cPresence = pCD->pSD->numWorkspaces;
  307. }
  308. }
  309. if (cPresence < pCD->numInhabited)
  310. {
  311. /* allocate bigger list */
  312. if (!(pPresence = (Atom *)
  313. XtRealloc ((char *)pPresence, pCD->numInhabited * sizeof(Atom))))
  314. {
  315. Warning (((char *)GETMESSAGE(76, 2, "Insufficient memory for workspace presence property")));
  316. }
  317. else
  318. {
  319. cPresence = pCD->numInhabited;
  320. }
  321. }
  322. for (i = 0; (i < pCD->numInhabited) && (i < cPresence) ; i++)
  323. {
  324. pPresence[i] = pCD->pWsList[i].wsID;
  325. }
  326. SetWorkspacePresence (pCD->client, pPresence,
  327. MIN(pCD->numInhabited, cPresence));
  328. } /* END OF FUNCTION UpdateWorkspacePresenceProperty */
  329. /*************************************<->*************************************
  330. *
  331. * AddPersistentWindow (pWS)
  332. *
  333. *
  334. * Description:
  335. * -----------
  336. * This function adds windows that want to be in all workspaces to
  337. * the workspace passed in.
  338. *
  339. * Inputs:
  340. * ------
  341. * pWS = pointer to workspace data
  342. *
  343. * Outputs:
  344. * --------
  345. *
  346. *************************************<->***********************************/
  347. void
  348. AddPersistentWindows(
  349. WmWorkspaceData *pWS)
  350. {
  351. WmScreenData *pSD = pWS->pSD;
  352. int i;
  353. ClientListEntry *pCLE;
  354. /*
  355. * For all the windows managed for this screen, see if they
  356. * want to be in all workspaces and add them to this workspace.
  357. */
  358. pCLE = pSD->clientList;
  359. while (1)
  360. {
  361. /*
  362. * Process all the non-icon client list entries
  363. */
  364. if ((pCLE->type == NORMAL_STATE) &&
  365. (pCLE->pCD->putInAll))
  366. {
  367. AddClientToWorkspaces( pCLE->pCD, &(pWS->id), 1 );
  368. }
  369. /*
  370. * Test for exit condition and advance client list pointer
  371. */
  372. if (pCLE == pSD->lastClient)
  373. break;
  374. else
  375. pCLE = pCLE->nextSibling;
  376. }
  377. } /* END OF FUNCTION AddPersistentWindows */
  378. /*************************************<->*************************************
  379. *
  380. * CreateWorkspace (pSD, pchTitle)
  381. *
  382. *
  383. * Description:
  384. * -----------
  385. * This function creates a new workspace.
  386. *
  387. * Inputs:
  388. * ------
  389. * pSD = pointer to screen data
  390. * pchTitle = user-visible title for the workspace (may be NULL)
  391. *
  392. * Outputs:
  393. * --------
  394. * Returns pointer to workspace data if successful.
  395. *
  396. *************************************<->***********************************/
  397. WmWorkspaceData *
  398. CreateWorkspace(
  399. WmScreenData *pSD,
  400. unsigned char *pchTitle )
  401. {
  402. WmWorkspaceData *pWS = NULL;
  403. String string;
  404. int iActiveWS;
  405. /*
  406. * Allocate more workspace datas if we have no spares
  407. */
  408. if (pSD->numWsDataAllocated <= pSD->numWorkspaces)
  409. {
  410. iActiveWS = (pSD->pActiveWS - pSD->pWS) / sizeof (WmWorkspaceData);
  411. pSD->numWsDataAllocated += WS_ALLOC_AMOUNT;
  412. pSD->pWS = (WmWorkspaceData *) XtRealloc ((char *)pSD->pWS,
  413. pSD->numWsDataAllocated * sizeof(WmWorkspaceData));
  414. pSD->pActiveWS = &(pSD->pWS[iActiveWS]);
  415. }
  416. /*
  417. * Give this workspace a name
  418. */
  419. pWS = &pSD->pWS[pSD->numWorkspaces];
  420. string = (String) GenerateWorkspaceName (pSD, pSD->numWorkspaces);
  421. pWS->name = XtNewString (string);
  422. /*
  423. * Initialize the workspace data structure
  424. */
  425. InitWmWorkspace (pWS, pSD);
  426. if (pchTitle)
  427. {
  428. if (pWS->title)
  429. XmStringFree (pWS->title);
  430. pWS->title = XmStringCreateLocalized ((char *)pchTitle);
  431. }
  432. /*
  433. * bump workspace count
  434. */
  435. pSD->numWorkspaces++;
  436. /*
  437. * update the properties that announce workspace info
  438. */
  439. SetWorkspaceInfoProperty (pWS);
  440. SetWorkspaceListProperty (pSD);
  441. SaveWorkspaceResources(pWS, (WM_RES_WORKSPACE_LIST |
  442. WM_RES_WORKSPACE_COUNT |
  443. WM_RES_WORKSPACE_TITLE));
  444. dtSendWorkspaceModifyNotification(pSD, pWS->id, DtWSM_REASON_ADD);
  445. /*
  446. * Insure there's an iconbox for this workspace
  447. */
  448. if (pSD->useIconBox)
  449. {
  450. AddIconBoxForWorkspace (pWS);
  451. }
  452. /*
  453. * Add windows to this workspaces that want to be in "all"
  454. * workspaces.
  455. */
  456. AddPersistentWindows (pWS);
  457. /*
  458. * Update workspace presence dialog data
  459. */
  460. UpdatePresenceWorkspaces(pSD);
  461. return (pWS);
  462. } /* END OF FUNCTION CreateWorkspace */
  463. /*************************************<->*************************************
  464. *
  465. * DeleteWorkspace (pWS)
  466. *
  467. *
  468. * Description:
  469. * -----------
  470. * This function deletes a workspace.
  471. *
  472. * Inputs:
  473. * ------
  474. * pWS = pointer to screen data
  475. *
  476. * Outputs:
  477. * --------
  478. * Returns pointer to workspace data if successful.
  479. *
  480. *************************************<->***********************************/
  481. void
  482. DeleteWorkspace(
  483. WmWorkspaceData *pWS )
  484. {
  485. WmWorkspaceData *pWSdest; /* destination WS */
  486. int i, iNextWs;
  487. ClientData *pCD;
  488. WmScreenData *pSD = pWS->pSD;
  489. Atom aOldId;
  490. if (pSD->numWorkspaces > 1)
  491. {
  492. /*
  493. * Find index for "next" workspace
  494. */
  495. for (iNextWs = 0; iNextWs < pSD->numWorkspaces; iNextWs++)
  496. {
  497. if (pSD->pWS[iNextWs].id == pWS->id)
  498. {
  499. iNextWs++;
  500. break;
  501. }
  502. }
  503. /* check bounds and wrap */
  504. if (iNextWs >= pSD->numWorkspaces)
  505. iNextWs = 0;
  506. /*
  507. * Determine default destination for clients that exist
  508. * only in the workspace being deleted.
  509. */
  510. if (pWS == ACTIVE_WS)
  511. {
  512. pWSdest = &(pSD->pWS[iNextWs]);
  513. }
  514. else
  515. {
  516. /*
  517. * Use the "current" workspace as the default destination
  518. */
  519. pWSdest = ACTIVE_WS;
  520. }
  521. /*
  522. * Move all clients out of this workspace
  523. */
  524. while (pWS->numClients > 0)
  525. {
  526. /* repeatedly remove the first one until all are gone */
  527. pCD = pWS->ppClients[0];
  528. if (pCD->numInhabited == 1)
  529. {
  530. if (!(pCD->clientFlags & (ICON_BOX)))
  531. {
  532. AddClientToWorkspaces (pCD, &(pWSdest->id), 1);
  533. }
  534. }
  535. RemoveClientFromWorkspaces (pCD, &(pWS->id), 1);
  536. }
  537. /*
  538. * If we're deleting the current workspace,
  539. * then change to another workspace.
  540. */
  541. if (pWS == ACTIVE_WS)
  542. {
  543. ChangeToWorkspace (pWSdest);
  544. }
  545. /*
  546. * Save the workspace ID for the notification message.
  547. */
  548. aOldId = pWS->id;
  549. /*
  550. * Destroy the icon box for the workspace if one was used
  551. */
  552. if (pSD->useIconBox)
  553. {
  554. DestroyIconBox (pWS);
  555. }
  556. /*
  557. * Delete the property containing information on this workspace
  558. */
  559. DeleteWorkspaceInfoProperty (pWS);
  560. /*
  561. * Delete the workspace data structures
  562. */
  563. if (pWS->backdrop.imagePixmap)
  564. {
  565. if (!XmDestroyPixmap (XtScreen(pWS->workspaceTopLevelW),
  566. pWS->backdrop.imagePixmap))
  567. {
  568. /* not in Xm pixmap cache */
  569. }
  570. }
  571. /* free pWS->backdrop.image */
  572. if ((pWS->backdrop.flags & BACKDROP_IMAGE_ALLOCED) &&
  573. (pWS->backdrop.image))
  574. {
  575. free (pWS->backdrop.image);
  576. }
  577. /*
  578. * Free up icon placement data
  579. */
  580. if (wmGD.iconAutoPlace)
  581. {
  582. if (pWS->IPData.placeList != NULL)
  583. XtFree ((char *) pWS->IPData.placeList);
  584. if (pWS->IPData.placementRowY != NULL)
  585. XtFree ((char *) pWS->IPData.placementRowY);
  586. if (pWS->IPData.placementColX != NULL)
  587. XtFree ((char *) pWS->IPData.placementColX);
  588. }
  589. XtFree ((char *) pWS->name);
  590. XmStringFree (pWS->title);
  591. XtFree ((char *) pWS->ppClients);
  592. if (pWS->iconBoxGeometry) XtFree ((char *) pWS->iconBoxGeometry);
  593. XtDestroyWidget (pWS->workspaceTopLevelW);
  594. /*
  595. * Compress the list of workspaces if we're not deleting
  596. * the last one. (Do piece-wise to avoid overlapping copy
  597. * problems).
  598. */
  599. if (iNextWs > 0)
  600. {
  601. WmWorkspaceData *pWSdest;
  602. WmWorkspaceData *pWSsrc;
  603. int j;
  604. pWSdest = pWS;
  605. pWSsrc = &(pSD->pWS[iNextWs]);
  606. for (j=iNextWs; j < pSD->numWorkspaces; j++)
  607. {
  608. memcpy (pWSdest, pWSsrc, sizeof(WmWorkspaceData));
  609. if (pSD->pActiveWS == pWSsrc)
  610. {
  611. pSD->pActiveWS = pWSdest;
  612. }
  613. pWSdest++;
  614. pWSsrc++;
  615. }
  616. }
  617. /*
  618. * We now have one less workspace.
  619. */
  620. pSD->numWorkspaces--;
  621. /*
  622. * Update the properties that announce workspace info.
  623. */
  624. SetWorkspaceListProperty (pSD);
  625. SaveWorkspaceResources(pWSdest,
  626. (WM_RES_WORKSPACE_LIST | WM_RES_WORKSPACE_COUNT));
  627. dtSendWorkspaceModifyNotification(pSD, aOldId, DtWSM_REASON_DELETE);
  628. /*
  629. * Update workspace presence dialog data
  630. */
  631. UpdatePresenceWorkspaces(pSD);
  632. }
  633. } /* END OF FUNCTION DeleteWorkspace */
  634. /*************************************<->*************************************
  635. *
  636. * ProcessDtWmHints (pCD)
  637. *
  638. *
  639. * Description:
  640. * -----------
  641. * Process the _DT_WM_HINTS property on the window (if any).
  642. *
  643. *
  644. * Inputs:
  645. * ------
  646. * pCD = pointer to client data
  647. *
  648. *
  649. * Outputs:
  650. * -------
  651. * pCD = may be changed.
  652. *
  653. *************************************<->***********************************/
  654. void
  655. ProcessDtWmHints (ClientData *pCD)
  656. {
  657. DtWmHints *pHints;
  658. Atom property;
  659. long saveFunctions;
  660. /*
  661. * Retrieve the _DT_WM_HINTS property if it exists.
  662. */
  663. property = XmInternAtom(DISPLAY, _XA_DT_WM_HINTS, False);
  664. if (
  665. (HasProperty (pCD, property))
  666. && (_DtWsmGetDtWmHints (DISPLAY, pCD->client, &pHints) == Success))
  667. {
  668. pCD->clientFlags |= GOT_DT_WM_HINTS;
  669. if (pHints->flags & DtWM_HINTS_FUNCTIONS)
  670. {
  671. if (pHints->functions & DtWM_FUNCTION_ALL)
  672. {
  673. /* client indicating inapplicable functions */
  674. pCD->dtwmFunctions &= ~(pHints->functions);
  675. }
  676. else
  677. {
  678. /* client indicating applicable functions */
  679. pCD->dtwmFunctions &= pHints->functions;
  680. }
  681. }
  682. if (pHints->flags & DtWM_HINTS_BEHAVIORS)
  683. {
  684. /* set applicable behaviors */
  685. pCD->dtwmBehaviors = pHints->behaviors;
  686. if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
  687. {
  688. /*
  689. * if this is a restored subpanel, remove the
  690. * DtWM_BEHAVIOR_SUB_RESTORED bit so the next
  691. * time through the subpanel will behave as an
  692. * existing subpanel
  693. */
  694. pHints->behaviors &= ~DtWM_BEHAVIOR_SUB_RESTORED;
  695. _DtWsmSetDtWmHints (DISPLAY, pCD->client, pHints);
  696. }
  697. }
  698. XFree ((char*)pHints);
  699. }
  700. if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_PANEL)
  701. {
  702. /* put it in all workspaces */
  703. saveFunctions = pCD->dtwmFunctions;
  704. pCD->dtwmFunctions |= DtWM_FUNCTION_OCCUPY_WS;
  705. F_AddToAllWorkspaces (NULL, pCD, NULL);
  706. pCD->dtwmFunctions = saveFunctions;
  707. pCD->clientFlags |= FRONT_PANEL_BOX ;
  708. }
  709. } /* END OF ProcessDtWmHints */
  710. /*************************************<->*************************************
  711. *
  712. * GetClientWorkspaceInfo (pCD, manageFlags);
  713. *
  714. *
  715. * Description:
  716. * -----------
  717. * This function sets up the portion of client data that has to
  718. * do with workspaces
  719. *
  720. * Inputs:
  721. * ------
  722. * pCD = pointer to client data (only partly initialized!!)
  723. * manageFlags = tells us, in particular, if we're restarting.
  724. *
  725. * Outputs:
  726. * --------
  727. * pCD = updated client data
  728. *
  729. *************************************<->***********************************/
  730. Boolean
  731. GetClientWorkspaceInfo(
  732. ClientData *pCD,
  733. long manageFlags )
  734. {
  735. Atom *pIDs;
  736. int i;
  737. unsigned int numIDs = 0;
  738. Boolean bAll;
  739. /*
  740. * Allocate initial workspace ID list
  741. * fill with NULL IDs
  742. */
  743. if ((pCD->pWsList = (WsClientData *)
  744. XtMalloc(pCD->pSD->numWorkspaces * sizeof(WsClientData))) == NULL)
  745. {
  746. Warning (((char *)GETMESSAGE(76, 4, "Insufficient memory for client data")));
  747. return (False);
  748. }
  749. pCD->currentWsc = 0;
  750. pCD->pWorkspaceHints = NULL;
  751. pCD->sizeWsList = pCD->pSD->numWorkspaces;
  752. pCD->numInhabited = 0; /* no valid ones yet */
  753. for (i = 0; i < pCD->pSD->numWorkspaces; i++)
  754. {
  755. pCD->pWsList[i].wsID = None;
  756. pCD->pWsList[i].iconPlace = NO_ICON_PLACE;
  757. pCD->pWsList[i].iconX = 0;
  758. pCD->pWsList[i].iconY = 0;
  759. pCD->pWsList[i].iconFrameWin = None;
  760. pCD->pWsList[i].pIconBox = NULL;
  761. }
  762. pCD->putInAll = bAll = False;
  763. /*
  764. * Determine initial workspace set.
  765. *
  766. * If this is a secondary window, use the hints from the
  767. * transient tree leader.
  768. *
  769. * Else if we're restarting, then use our own workspace presence.
  770. *
  771. * Else if a command line option is specified, use that.
  772. *
  773. * Else, if workspace hints are on the window, then use them.
  774. *
  775. * If none of the above work out, the window will be put into
  776. * the current workspace.
  777. */
  778. if (pCD->client &&
  779. ((pCD->transientLeader && GetLeaderPresence(pCD, &pIDs, &numIDs)) ||
  780. ((manageFlags & MANAGEW_WM_RESTART) &&
  781. GetMyOwnPresence (pCD, &pIDs, &numIDs)) ||
  782. (WorkspaceIsInCommand (DISPLAY, pCD, &pIDs, &numIDs)) ||
  783. (
  784. HasProperty (pCD, wmGD.xa_DT_WORKSPACE_HINTS)
  785. && (GetWorkspaceHints (DISPLAY, pCD->client, &pIDs, &numIDs, &bAll) ==
  786. Success))) &&
  787. numIDs)
  788. {
  789. /*
  790. * Got some workspace hints!
  791. */
  792. pCD->putInAll = bAll;
  793. ProcessWorkspaceHintList (pCD, pIDs, numIDs);
  794. }
  795. if (pCD->numInhabited == 0)
  796. {
  797. /*
  798. * If not in any workspaces, then put the client into
  799. * the current one.
  800. */
  801. PutClientIntoWorkspace (pCD->pSD->pActiveWS, pCD);
  802. }
  803. return (True);
  804. } /* END OF FUNCTION GetClientWorkspaceInfo */
  805. /*************************************<->*************************************
  806. *
  807. * WorkspaceIsInCommand (dpy, pCD, ppIDs, pNumIDs)
  808. *
  809. *
  810. * Description:
  811. * -----------
  812. * Determine if workspace specification is in command line for client
  813. *
  814. *
  815. * Inputs:
  816. * ------
  817. * dpy - pointer to display structure
  818. * pCD - ptr to client data
  819. * ppIDs - pointer for returning list of IDs
  820. * pNumIDs - number of IDs being returned
  821. *
  822. * Outputs:
  823. * -------
  824. * ppIDs - returned list of IDs
  825. * pNumIDs - number of IDs being returned
  826. *
  827. * Return - True if workspace option found, false otherwise
  828. *
  829. *
  830. * Comments:
  831. * --------
  832. * Malloc's memory that must be freed
  833. *
  834. *************************************<->***********************************/
  835. Boolean
  836. WorkspaceIsInCommand(
  837. Display *dpy,
  838. ClientData *pCD,
  839. WorkspaceID **ppIDs,
  840. unsigned int *pNumIDs )
  841. {
  842. int wmcArgc;
  843. char **wmcArgv = NULL;
  844. Boolean rval = False;
  845. unsigned char *pch = NULL;
  846. XTextProperty clientMachineProp;
  847. if (FindClientDBMatch(pCD, (char **)&pch))
  848. {
  849. if (pch)
  850. {
  851. if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
  852. {
  853. rval = True;
  854. }
  855. XtFree((char *)pch);
  856. }
  857. }
  858. else if (HasProperty (pCD, XA_WM_COMMAND) &&
  859. XGetCommand (dpy, pCD->client, &wmcArgv, &wmcArgc) &&
  860. (wmcArgv != NULL))
  861. {
  862. if (pCD->pSD->remainingSessionItems)
  863. {
  864. if(!(XGetWMClientMachine(dpy, pCD->client, &clientMachineProp)))
  865. {
  866. clientMachineProp.value = NULL;
  867. }
  868. if (FindDtSessionMatch(wmcArgc, wmcArgv, pCD, pCD->pSD,
  869. (char **)&pch,
  870. (char *)clientMachineProp.value))
  871. {
  872. /*
  873. * If we found a match to a client description
  874. * in the DtSessionHints, use the information from
  875. * the Hints instead of the command line
  876. */
  877. if (pch)
  878. {
  879. if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
  880. {
  881. rval = True;
  882. }
  883. /*
  884. * free malloced memory containing workspace list
  885. */
  886. XtFree ((char *)pch);
  887. }
  888. }
  889. if (clientMachineProp.value)
  890. {
  891. XFree ((char*)clientMachineProp.value);
  892. }
  893. }
  894. if (!rval && FindWsNameInCommand (wmcArgc, wmcArgv, &pch))
  895. {
  896. if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
  897. {
  898. rval = True;
  899. }
  900. }
  901. if (wmcArgv != NULL)
  902. {
  903. XFreeStringList (wmcArgv);
  904. }
  905. }
  906. return (rval);
  907. } /* END OF FUNCTION WorkspaceIsInCommand */
  908. /*************************************<->*************************************
  909. *
  910. * ConvertNamesToIDs (pSD, pch, ppAtoms, pNumAtoms)
  911. *
  912. *
  913. * Description:
  914. * -----------
  915. * Takes a string containing a list of names separated by white space
  916. * and converts it to a list of workspace IDs.
  917. *
  918. * Inputs:
  919. * ------
  920. * pSD - pointer to screen data
  921. * pchIn - pointer to original string
  922. * ppAtoms - pointer to an atom pointer (for returning list pointer)
  923. * pNumAtoms - pointer to the number of atoms being returned.
  924. *
  925. * Outputs:
  926. * -------
  927. * *ppAtoms - points to a list of atoms returned.
  928. * *pNumAtoms - the number of atoms being returned.
  929. *
  930. * Return - True if some Atoms are being returned
  931. *
  932. * Comments:
  933. * --------
  934. * Processes local copy of string so that pch is not modified.
  935. *
  936. * The list of atoms returned has been dynamically allocated.
  937. * Please XtFree() it when you're done.
  938. *
  939. *************************************<->***********************************/
  940. Boolean
  941. ConvertNamesToIDs(
  942. WmScreenData *pSD,
  943. unsigned char *pchIn,
  944. WorkspaceID **ppAtoms,
  945. unsigned int *pNumAtoms )
  946. {
  947. unsigned char *pchLocal, *pch, *pchName;
  948. int num = 0;
  949. int numLocalIDs;
  950. WorkspaceID *pLocalIDs;
  951. if ((pLocalIDs = (WorkspaceID *) XtMalloc (WS_ALLOC_AMOUNT *
  952. sizeof(WorkspaceID))) == NULL)
  953. {
  954. Warning (((char *)GETMESSAGE(76, 5, "Insufficient Memory (ConvertNamesToIDs)")));
  955. ExitWM (WM_ERROR_EXIT_VALUE);
  956. }
  957. numLocalIDs = WS_ALLOC_AMOUNT;
  958. if (pchIn && (pchLocal = (unsigned char *) XtMalloc(1+strlen((char *)pchIn))))
  959. {
  960. strcpy ((char *)pchLocal, (char *)pchIn);
  961. pch = pchLocal;
  962. while ((pchName = GetSmartString (&pch)))
  963. {
  964. int iwsx;
  965. XmString xms;
  966. /*
  967. * Check workspace for workspace titles; map to
  968. * workspace names.
  969. */
  970. xms = XmStringCreateLocalized ((char *)pchName);
  971. for (iwsx = 0; iwsx < pSD->numWorkspaces; iwsx++)
  972. {
  973. if (XmStringCompare (xms, pSD->pWS[iwsx].title))
  974. {
  975. break;
  976. }
  977. }
  978. XmStringFree (xms);
  979. if (iwsx < pSD->numWorkspaces)
  980. {
  981. /*
  982. * Found a workspace title we've got,
  983. * use id for workspace name
  984. */
  985. pLocalIDs[num] = pSD->pWS[iwsx].id;
  986. num++;
  987. }
  988. else
  989. {
  990. /*
  991. * Try for match on workspace name
  992. */
  993. pLocalIDs[num] = (WorkspaceID)
  994. XInternAtom (DISPLAY, (char *)pchName, False);
  995. num++;
  996. }
  997. if (num >= numLocalIDs)
  998. {
  999. /* list too small */
  1000. numLocalIDs += WS_ALLOC_AMOUNT;
  1001. if ((pLocalIDs = (WorkspaceID *) XtRealloc ((char *)pLocalIDs,
  1002. numLocalIDs * sizeof(WorkspaceID))) == NULL)
  1003. {
  1004. Warning (((char *)GETMESSAGE(76, 6, "Insufficient Memory (ConvertNamesToIDs)")));
  1005. ExitWM (WM_ERROR_EXIT_VALUE);
  1006. }
  1007. }
  1008. }
  1009. XtFree ((char *)pchLocal);
  1010. }
  1011. *ppAtoms = pLocalIDs;
  1012. *pNumAtoms = num;
  1013. return (num != 0);
  1014. } /* END OF FUNCTION ConvertNamesToIDs */
  1015. /*************************************<->*************************************
  1016. *
  1017. * CheckForPutInAllRequest (pCD, pIDs, numIDs)
  1018. *
  1019. *
  1020. * Description:
  1021. * -----------
  1022. * Tests for the presence of the "all" atom in the atom list
  1023. * and sets the "putInAll" flag on the client.
  1024. *
  1025. * Inputs:
  1026. * ------
  1027. * pCD - pointer to client data
  1028. * pIDs - pointer to ID list
  1029. * numIDs - number of IDs in list
  1030. *
  1031. * Outputs:
  1032. * -------
  1033. * pCD - putInAll member may be set
  1034. *
  1035. *************************************<->***********************************/
  1036. void
  1037. CheckForPutInAllRequest(
  1038. ClientData *pCD,
  1039. Atom *pIDs,
  1040. unsigned int numIDs )
  1041. {
  1042. unsigned int i;
  1043. for (i = 0; (i < numIDs) && !(pCD->putInAll); i++)
  1044. {
  1045. if (pIDs[i] == wmGD.xa_ALL_WORKSPACES)
  1046. {
  1047. pCD->putInAll = True;
  1048. break;
  1049. }
  1050. }
  1051. } /* END OF FUNCTION CheckForPutInAllRequest */
  1052. /*************************************<->*************************************
  1053. *
  1054. * FindWsNameInCommand (argc, argv, ppch)
  1055. *
  1056. *
  1057. * Description:
  1058. * -----------
  1059. * Finds and returns the workspace name option in the command line
  1060. * (if any)
  1061. *
  1062. * Inputs:
  1063. * ------
  1064. * argc - argument count
  1065. * argv - argument list
  1066. * ppch - string pointer to return
  1067. *
  1068. *
  1069. * Outputs:
  1070. * -------
  1071. * *ppch - points to ws name (if found)
  1072. *
  1073. * Return - True if wsname found
  1074. *
  1075. *
  1076. * Comments:
  1077. * --------
  1078. *************************************<->***********************************/
  1079. Boolean
  1080. FindWsNameInCommand(
  1081. int argc,
  1082. char *argv[],
  1083. unsigned char **ppch )
  1084. {
  1085. #define XRM_OPT "-xrm"
  1086. #define WSLIST "*workspaceList:"
  1087. #define WSLIST_LEN 14
  1088. int i = 1;
  1089. Boolean rval = False;
  1090. unsigned char *pch, *pchTmp, *pch0;
  1091. unsigned char *pchRes, *pchValue;
  1092. if (argc > 0)
  1093. {
  1094. while (--argc && !rval)
  1095. {
  1096. if (!strcmp(argv[i], XRM_OPT) && (argc > 1))
  1097. {
  1098. /*
  1099. * found "-xrm", now look at resource spec
  1100. */
  1101. pch0 = (unsigned char *) strdup (argv[i+1]);
  1102. if (!pch0)
  1103. {
  1104. Warning (((char *)GETMESSAGE(76, 7, "Insufficient memory")));
  1105. ExitWM (WM_ERROR_EXIT_VALUE);
  1106. }
  1107. pch = pch0;
  1108. /* strip off quotes ,
  1109. * separate two halve of resource spec
  1110. */
  1111. pchRes = GetSmartString (&pch);
  1112. pchValue = pch;
  1113. if ((*pchRes) && (*pch))
  1114. {
  1115. /* Erase colon at end of resource name */
  1116. pch = (unsigned char *) strrchr((char *)pchRes, ':');
  1117. if (pch)
  1118. {
  1119. *pch = '\0';
  1120. }
  1121. /* find beginning of last component of resource
  1122. * spec
  1123. */
  1124. pch = (unsigned char *) strrchr ((char *)pchRes, '*');
  1125. pchTmp = (unsigned char *) strrchr ((char *)pchRes, '.');
  1126. if (pchTmp > pch)
  1127. {
  1128. pch = pchTmp;
  1129. }
  1130. if (pch && *pch && *(pch+1))
  1131. {
  1132. pch += 1;
  1133. }
  1134. /* compare resource with our resource */
  1135. if ( (!strcmp ((char *)pch, WmNworkspaceList)) ||
  1136. (!strcmp ((char *)pch, WmCWorkspaceList)))
  1137. {
  1138. /* match, compute return position in
  1139. passed in string */
  1140. *ppch = (unsigned char *)
  1141. (argv[i+1] + (pchValue - pch0));
  1142. rval = True;
  1143. XtFree ((char *)pch0);
  1144. pch0 = NULL;
  1145. }
  1146. }
  1147. i++; /* skip next arg */
  1148. argc--;
  1149. if (pch0)
  1150. {
  1151. XtFree ((char *)pch0);
  1152. }
  1153. }
  1154. i++;
  1155. }
  1156. }
  1157. return (rval);
  1158. } /* END OF FUNCTION FindWsNameInCommand */
  1159. /*************************************<->*************************************
  1160. *
  1161. * PutClientIntoWorkspace (pWS, pCD)
  1162. *
  1163. *
  1164. * Description:
  1165. * -----------
  1166. * This function updates the data for the client and workspace to
  1167. * reflect the presence of the client in the workspace.
  1168. *
  1169. * Inputs:
  1170. * ------
  1171. * pWS = pointer to workspace data
  1172. * pCD = pointer to client data
  1173. *
  1174. * Outputs:
  1175. * --------
  1176. *
  1177. *************************************<->***********************************/
  1178. void
  1179. PutClientIntoWorkspace(
  1180. WmWorkspaceData *pWS,
  1181. ClientData *pCD )
  1182. {
  1183. int i = pCD->numInhabited;
  1184. int iAdded, j, k;
  1185. /* insure the client's got enough workspace data */
  1186. if (pCD->sizeWsList < pCD->pSD->numWorkspaces)
  1187. {
  1188. iAdded = pCD->pSD->numWorkspaces - pCD->sizeWsList;
  1189. pCD->sizeWsList = pCD->pSD->numWorkspaces;
  1190. pCD->pWsList = (WsClientData *)
  1191. XtRealloc((char *)pCD->pWsList,
  1192. (pCD->pSD->numWorkspaces * sizeof(WsClientData)));
  1193. /* intialized new data */
  1194. j = pCD->sizeWsList - 1;
  1195. for (j=1; j <= iAdded; j++)
  1196. {
  1197. k = pCD->sizeWsList - j;
  1198. pCD->pWsList[k].iconPlace = NO_ICON_PLACE;
  1199. pCD->pWsList[k].iconX = 0;
  1200. pCD->pWsList[k].iconY = 0;
  1201. pCD->pWsList[k].iconFrameWin = (Window) 0;
  1202. pCD->pWsList[k].pIconBox = NULL;
  1203. }
  1204. }
  1205. /* update the client's list of workspace data */
  1206. pCD->pWsList[i].wsID = pWS->id;
  1207. pCD->numInhabited++;
  1208. if (!(pCD->clientFlags & WM_INITIALIZATION))
  1209. {
  1210. /*
  1211. * Make sure there's an icon
  1212. * (Don't do this during initialization, the pCD not
  1213. * ready for icon making yet).
  1214. */
  1215. InsureIconForWorkspace (pWS, pCD);
  1216. }
  1217. /* update the workspace list of clients */
  1218. AddClientToWsList (pWS, pCD);
  1219. } /* END OF FUNCTION PutClientIntoWorkspace */
  1220. /*************************************<->*************************************
  1221. *
  1222. * TakeClientOutOfWorkspace (pWS, pCD)
  1223. *
  1224. *
  1225. * Description:
  1226. * -----------
  1227. * This function updates the data for the client and the workspace
  1228. * to reflect the removal of the client from the workspace.
  1229. *
  1230. * Inputs:
  1231. * ------
  1232. * pWS = pointer to workspace data
  1233. * pCD = pointer to client data
  1234. *
  1235. * Outputs:
  1236. * --------
  1237. *
  1238. *************************************<->***********************************/
  1239. void
  1240. TakeClientOutOfWorkspace(
  1241. WmWorkspaceData *pWS,
  1242. ClientData *pCD )
  1243. {
  1244. int ixA;
  1245. Boolean Copying = False;
  1246. WsClientData *pWsc;
  1247. if (pWS && pCD && ClientInWorkspace(pWS, pCD))
  1248. {
  1249. /*
  1250. * Clean up icon
  1251. */
  1252. if (!pCD->transientLeader)
  1253. {
  1254. pWsc = GetWsClientData (pWS, pCD);
  1255. if ((pCD->pSD->useIconBox) &&
  1256. (pWsc->pIconBox) &&
  1257. (pCD->clientFunctions & MWM_FUNC_MINIMIZE))
  1258. {
  1259. DeleteIconFromBox (pWS->pIconBox, pCD);
  1260. }
  1261. else if (wmGD.iconAutoPlace)
  1262. {
  1263. /*
  1264. * Free up root icon spot
  1265. */
  1266. if ((pWsc->iconPlace != NO_ICON_PLACE) &&
  1267. (pWS->IPData.placeList[pWsc->iconPlace].pCD == pCD))
  1268. {
  1269. pWS->IPData.placeList[pWsc->iconPlace].pCD = NULL;
  1270. pWsc->iconPlace = NO_ICON_PLACE;
  1271. }
  1272. }
  1273. }
  1274. /*
  1275. * Remove the selected workspace and copy the remaining ones
  1276. * up. (Do piece-wise to avoid overlapping copy.)
  1277. */
  1278. for (ixA = 0; ixA < pCD->numInhabited; ixA++)
  1279. {
  1280. if (Copying)
  1281. {
  1282. memcpy (&pCD->pWsList[ixA-1], &pCD->pWsList[ixA],
  1283. sizeof(WsClientData));
  1284. }
  1285. else if (pCD->pWsList[ixA].wsID == pWS->id)
  1286. {
  1287. /*
  1288. * This is the one we're removing, start copying here.
  1289. */
  1290. Copying = True;
  1291. }
  1292. }
  1293. /*
  1294. * Decrement the number of workspaces inhabited.
  1295. */
  1296. pCD->numInhabited--;
  1297. /* update the workspaces list of clients */
  1298. RemoveClientFromWsList (pWS, pCD);
  1299. }
  1300. #ifdef DEBUG
  1301. else
  1302. {
  1303. Warning("TakeClientOutOfWorkspace: null workspace passed in.");
  1304. }
  1305. #endif /* DEBUG */
  1306. } /* END OF FUNCTION TakeClientOutOfWorkspace */
  1307. /*************************************<->*************************************
  1308. *
  1309. * GetWorkspaceData (pSD, wsID)
  1310. *
  1311. *
  1312. * Description:
  1313. * -----------
  1314. * This function finds the data that is associated with a workspace ID.
  1315. *
  1316. * Inputs:
  1317. * ------
  1318. * pSD = pointer to screen data
  1319. * wsID = workspace ID
  1320. *
  1321. * Outputs:
  1322. * --------
  1323. * Function returns a pointer to the workspace data if successful,
  1324. * or NULL if unsuccessful.
  1325. *
  1326. *************************************<->***********************************/
  1327. WmWorkspaceData *
  1328. GetWorkspaceData(
  1329. WmScreenData *pSD,
  1330. WorkspaceID wsID )
  1331. {
  1332. WmWorkspaceData *pWS = NULL;
  1333. int i;
  1334. for (i=0; i < pSD->numWorkspaces; i++)
  1335. {
  1336. if (pSD->pWS[i].id == wsID)
  1337. {
  1338. pWS = &pSD->pWS[i];
  1339. break;
  1340. }
  1341. }
  1342. #ifdef DEBUG
  1343. if (!pWS)
  1344. {
  1345. /* failed to find one */
  1346. Warning ("Failed to find workspace data");
  1347. }
  1348. #endif
  1349. return (pWS);
  1350. } /* END OF FUNCTION GetWorkspaceData */
  1351. /*************************************<->*************************************
  1352. *
  1353. * GenerateWorkspaceName (pSD, wsnum)
  1354. *
  1355. *
  1356. * Description:
  1357. * -----------
  1358. * This function generates and returns a workspace string name from
  1359. * a small number passed in.
  1360. *
  1361. * Inputs:
  1362. * ------
  1363. * pSD = pointer to screen data
  1364. * wsNum = number for workspace
  1365. *
  1366. *
  1367. * Outputs:
  1368. * -------
  1369. * returns pointer to statically allocated data. You must copy it
  1370. * to your local buffer.
  1371. *
  1372. * Comments:
  1373. * ---------
  1374. * Name is of the form ws<n> where <n> is a number.
  1375. *
  1376. *************************************<->***********************************/
  1377. unsigned char *
  1378. GenerateWorkspaceName(
  1379. WmScreenData *pSD,
  1380. int wsnum )
  1381. {
  1382. static unsigned char nameReturned[13];
  1383. int i, j;
  1384. /*
  1385. * Nice n-squared algorithm...
  1386. * (This should be OK for small number of workspaces)
  1387. */
  1388. for (i=0; i <= pSD->numWorkspaces; i++)
  1389. {
  1390. /* generate a name */
  1391. sprintf ((char *)nameReturned, "ws%d", i);
  1392. if (!DuplicateWorkspaceName (pSD, nameReturned, wsnum))
  1393. break;
  1394. }
  1395. return (nameReturned);
  1396. } /* END OF FUNCTION GenerateWorkspaceName */
  1397. /*************************************<->*************************************
  1398. *
  1399. * InWindowList (w, wl, num)
  1400. *
  1401. *
  1402. * Description:
  1403. * -----------
  1404. * This function determines if a window is in a list of windows
  1405. *
  1406. * Inputs:
  1407. * ------
  1408. * w = window of interest
  1409. * wl = list of windows
  1410. * num = number of windows in wl
  1411. *
  1412. *
  1413. * Outputs:
  1414. * -------
  1415. * The function returns "True" if "w" appears in "wl"
  1416. *
  1417. *************************************<->***********************************/
  1418. Boolean
  1419. InWindowList(
  1420. Window w,
  1421. Window wl[],
  1422. int num )
  1423. {
  1424. int i;
  1425. Boolean rval = False;
  1426. for (i = 0; (i < num) && !rval; i++)
  1427. {
  1428. if (w == wl[i])
  1429. {
  1430. rval = True;
  1431. }
  1432. }
  1433. return (rval);
  1434. } /* END OF FUNCTION InWindowList */
  1435. /*************************************<->*************************************
  1436. *
  1437. * ClientInWorkspace (pWS, pCD)
  1438. *
  1439. *
  1440. * Description:
  1441. * -----------
  1442. * This function determines if a client is in a workspace
  1443. *
  1444. * Inputs:
  1445. * ------
  1446. * pWS = pointer to workspace data
  1447. * pCD = pointer to client data
  1448. *
  1449. * Outputs:
  1450. * -------
  1451. * The function returns "True" if client pCD is in workspace pWS
  1452. *
  1453. *************************************<->***********************************/
  1454. Boolean
  1455. ClientInWorkspace(
  1456. WmWorkspaceData *pWS,
  1457. ClientData *pCD )
  1458. {
  1459. int i;
  1460. Boolean rval = False;
  1461. for (i = 0; (i < pCD->numInhabited) && !rval; i++)
  1462. {
  1463. if (pWS->id == pCD->pWsList[i].wsID)
  1464. {
  1465. rval = True;
  1466. }
  1467. }
  1468. return (rval);
  1469. } /* END OF FUNCTION ClientInWorkspace */
  1470. /*************************************<->*************************************
  1471. *
  1472. * GetWsClientData (pWS, pCD)
  1473. *
  1474. *
  1475. * Description:
  1476. * -----------
  1477. * This function returns a pointer to the client's specific data for
  1478. * this workspace
  1479. *
  1480. * Inputs:
  1481. * ------
  1482. * pWS = pointer to workspace data
  1483. * pCD = pointer to client data
  1484. *
  1485. * Outputs:
  1486. * -------
  1487. * The function returns a pointer to the client's data for this
  1488. * workspace. If the client isn't in the workspace, an error is
  1489. * printed and the first datum in the workspace list is returned.
  1490. *
  1491. *************************************<->***********************************/
  1492. WsClientData *
  1493. GetWsClientData(
  1494. WmWorkspaceData *pWS,
  1495. ClientData *pCD )
  1496. {
  1497. int i;
  1498. WsClientData *pWsc = NULL;
  1499. for (i = 0; (i < pCD->numInhabited) && !pWsc; i++)
  1500. {
  1501. if (pWS->id == pCD->pWsList[i].wsID)
  1502. {
  1503. pWsc = &pCD->pWsList[i];
  1504. }
  1505. }
  1506. if (!pWsc)
  1507. {
  1508. pWsc = &pCD->pWsList[0];
  1509. }
  1510. return (pWsc);
  1511. } /* END OF FUNCTION GetWsClientData */
  1512. /*************************************<->*************************************
  1513. *
  1514. * SetClientWsIndex (pCD)
  1515. *
  1516. *
  1517. * Description:
  1518. * -----------
  1519. * This function sets the index into the client's array of workspace
  1520. * specific data. This index points to the data to be used for the
  1521. * currently active workspace.
  1522. *
  1523. * Inputs:
  1524. * ------
  1525. * pCD = pointer to client data
  1526. *
  1527. * Outputs:
  1528. * -------
  1529. * The function returns an index as described above. If the client is
  1530. * not in the currently active workspace, then the index returned is 0.
  1531. *
  1532. *************************************<->***********************************/
  1533. void
  1534. SetClientWsIndex(
  1535. ClientData *pCD )
  1536. {
  1537. int i;
  1538. WmWorkspaceData *pWS = pCD->pSD->pActiveWS;
  1539. for (i = 0; (i < pCD->numInhabited); i++)
  1540. {
  1541. if (pWS->id == pCD->pWsList[i].wsID)
  1542. {
  1543. break;
  1544. }
  1545. }
  1546. if (i >= pCD->numInhabited)
  1547. {
  1548. i = 0;
  1549. }
  1550. pCD->currentWsc = i;
  1551. } /* END OF FUNCTION SetClientWsIndex */
  1552. /*************************************<->*************************************
  1553. *
  1554. * ProcessWmWorkspaceHints (pCD)
  1555. *
  1556. *
  1557. * Description:
  1558. * -----------
  1559. * This function processes a change to the _DT_WORKSPACE_HINTS property
  1560. * on a window that we manage.
  1561. *
  1562. * Inputs:
  1563. * ------
  1564. * pCD = pointer to client data
  1565. *
  1566. * Outputs:
  1567. * -------
  1568. * Returns False if we ran out of memory or no hints.
  1569. * Returns True on success.
  1570. *
  1571. *************************************<->***********************************/
  1572. Boolean
  1573. ProcessWorkspaceHints(
  1574. ClientData *pCD )
  1575. {
  1576. Atom *pIDs;
  1577. int i, j;
  1578. unsigned int numIDs;
  1579. WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
  1580. Boolean rval = False;
  1581. Boolean InBoth;
  1582. Boolean bAll;
  1583. int numOld;
  1584. WorkspaceID *pDiff = NULL;
  1585. int numDiff;
  1586. numOld = pCD->numInhabited;
  1587. ReserveIdListSpace (numOld);
  1588. for (i = 0; i < numOld; i++)
  1589. {
  1590. pResIDs[i] = pCD->pWsList[i].wsID;
  1591. }
  1592. if ((pCD->client) &&
  1593. (GetWorkspaceHints (DISPLAY, pCD->client,
  1594. &pIDs, &numIDs, &bAll) == Success) &&
  1595. (bAll || (numIDs && (pDiff = (WorkspaceID *)
  1596. XtMalloc (sizeof(WorkspaceID) * MAX(numIDs, numOld))))))
  1597. {
  1598. /*
  1599. * Process request to put window in all workspaces
  1600. */
  1601. pCD->putInAll = bAll;
  1602. CheckForPutInAllRequest (pCD, pIDs, numIDs);
  1603. if (!pCD->putInAll)
  1604. {
  1605. /*
  1606. * Compute the ids to be removed.
  1607. */
  1608. numDiff = 0;
  1609. for (i=0; i < numOld; i++)
  1610. {
  1611. InBoth = False;
  1612. for (j=0; j < numIDs; j++)
  1613. {
  1614. if (pIDs[j] == pResIDs[i])
  1615. {
  1616. InBoth = True;
  1617. break;
  1618. }
  1619. }
  1620. if (!InBoth)
  1621. {
  1622. pDiff[numDiff++] = pResIDs[i];
  1623. }
  1624. }
  1625. /*
  1626. * Remove the client from the set of workspaces
  1627. */
  1628. if (numDiff)
  1629. {
  1630. RemoveClientFromWorkspaces (pCD, pDiff, numDiff);
  1631. }
  1632. }
  1633. /*
  1634. * Process request to put window in all workspaces
  1635. */
  1636. if (pCD->putInAll)
  1637. {
  1638. for (i=0; i<pCD->pSD->numWorkspaces; i++)
  1639. {
  1640. if (!ClientInWorkspace(&pCD->pSD->pWS[i], pCD))
  1641. {
  1642. AddClientToWorkspaces (pCD, &pCD->pSD->pWS[i].id, 1);
  1643. }
  1644. }
  1645. }
  1646. else
  1647. {
  1648. /*
  1649. * Compute the ids to be added.
  1650. */
  1651. numDiff = 0;
  1652. for (i=0; i < numIDs; i++)
  1653. {
  1654. InBoth = False;
  1655. for (j=0; j < numOld; j++)
  1656. {
  1657. if (pResIDs[j] == pIDs[i])
  1658. {
  1659. InBoth = True;
  1660. break;
  1661. }
  1662. }
  1663. if (!InBoth)
  1664. {
  1665. pDiff[numDiff++] = pIDs[i];
  1666. }
  1667. }
  1668. /*
  1669. * Add the client to the set of workspaces
  1670. */
  1671. if (numDiff)
  1672. {
  1673. AddClientToWorkspaces (pCD, pDiff, numDiff);
  1674. }
  1675. }
  1676. /*
  1677. * If the client is not in any workspaces, then
  1678. * put it in the current one
  1679. *
  1680. * !!! Is this right? !!!
  1681. */
  1682. if (pCD->numInhabited == 0)
  1683. {
  1684. AddClientToWorkspaces (pCD, &pSD->pActiveWS->id, 1);
  1685. }
  1686. /*
  1687. * Free up the old list of hints
  1688. */
  1689. if (pCD->pWorkspaceHints)
  1690. {
  1691. XFree ((char *)pCD->pWorkspaceHints);
  1692. }
  1693. if (pDiff)
  1694. {
  1695. XtFree ((char *)pDiff);
  1696. }
  1697. /*
  1698. * Save the new hints
  1699. */
  1700. pCD->pWorkspaceHints = pIDs;
  1701. pCD->numWorkspaceHints = numIDs;
  1702. /*
  1703. * Update the presence property
  1704. */
  1705. UpdateWorkspacePresenceProperty (pCD);
  1706. rval = True;
  1707. }
  1708. return (rval);
  1709. } /* END OF FUNCTION ProcessWorkspaceHints */
  1710. /*************************************<->*************************************
  1711. *
  1712. * InsureUniqueWorkspaceHints (pCD)
  1713. *
  1714. *
  1715. * Description:
  1716. * -----------
  1717. * This function processes the workspace hints and removes duplicates.
  1718. *
  1719. * Inputs:
  1720. * ------
  1721. * pCD = pointer to client data
  1722. *
  1723. * Outputs:
  1724. * -------
  1725. * May modify *pWorkspaceHints and numWorkspaceHints
  1726. *
  1727. *************************************<->***********************************/
  1728. static void
  1729. InsureUniqueWorkspaceHints(
  1730. ClientData *pCD )
  1731. {
  1732. int next, trail, i;
  1733. WorkspaceID *pID;
  1734. Boolean duplicate;
  1735. if (pCD->numWorkspaceHints < 2) return;
  1736. pID = pCD->pWorkspaceHints;
  1737. trail = 0;
  1738. next = 1;
  1739. while (next < pCD->numWorkspaceHints)
  1740. {
  1741. duplicate = False;
  1742. for (i = 0; i < next; i++)
  1743. {
  1744. if (pID [next] == pID [i])
  1745. {
  1746. /* duplicate found! */
  1747. duplicate = True;
  1748. break;
  1749. }
  1750. }
  1751. if (duplicate)
  1752. {
  1753. /* skip duplicates */
  1754. next++;
  1755. }
  1756. else
  1757. {
  1758. /* not a duplicate */
  1759. trail++;
  1760. if (next > trail)
  1761. {
  1762. /*
  1763. * We need to copy up over an old duplicate
  1764. */
  1765. pID [trail] = pID [next];
  1766. }
  1767. }
  1768. next++;
  1769. }
  1770. pCD->numWorkspaceHints = trail+1;
  1771. } /* END OF FUNCTION InsureUniqueWorkspaceHints */
  1772. /*************************************<->*************************************
  1773. *
  1774. * ProcessWorkspaceHintList (pCD, pIDs, numIDs)
  1775. *
  1776. *
  1777. * Description:
  1778. * -----------
  1779. * This function processes a list of workspace hints for a client.
  1780. *
  1781. * Inputs:
  1782. * ------
  1783. * pCD = pointer to client data
  1784. * pIDs = pointer to a list of workspace IDs
  1785. * numIDs = number of IDs in the list
  1786. *
  1787. * Outputs:
  1788. * -------
  1789. *
  1790. *************************************<->***********************************/
  1791. void
  1792. ProcessWorkspaceHintList(
  1793. ClientData *pCD,
  1794. WorkspaceID *pIDs,
  1795. unsigned int numIDs )
  1796. {
  1797. int i;
  1798. WmWorkspaceData *pWS;
  1799. if (numIDs > 0)
  1800. {
  1801. /*
  1802. * Keep these hints; make sure there are no duplicate
  1803. * workspace requests.
  1804. */
  1805. pCD->pWorkspaceHints = pIDs;
  1806. pCD->numWorkspaceHints = numIDs;
  1807. InsureUniqueWorkspaceHints (pCD);
  1808. numIDs = pCD->numWorkspaceHints;
  1809. if (pCD->pWorkspaceHints)
  1810. {
  1811. /*
  1812. * Process request to put window in all workspaces
  1813. */
  1814. CheckForPutInAllRequest (pCD, pIDs, numIDs);
  1815. if (pCD->putInAll)
  1816. {
  1817. for (i=0; i<pCD->pSD->numWorkspaces; i++)
  1818. {
  1819. PutClientIntoWorkspace (&pCD->pSD->pWS[i], pCD);
  1820. }
  1821. }
  1822. else
  1823. {
  1824. for (i=0; i<numIDs; i++)
  1825. {
  1826. /*
  1827. * Put the client into requested workspaces that
  1828. * exist.
  1829. */
  1830. if ((pWS = GetWorkspaceData (pCD->pSD,
  1831. pCD->pWorkspaceHints[i])))
  1832. {
  1833. PutClientIntoWorkspace (pWS, pCD);
  1834. }
  1835. }
  1836. }
  1837. }
  1838. }
  1839. } /* END OF FUNCTION ProcessWorkspaceHintList */
  1840. /*************************************<->*************************************
  1841. *
  1842. * RemoveSingleClientFromWorkspaces (pCD, pIDs, numIDs)
  1843. *
  1844. *
  1845. * Description:
  1846. * -----------
  1847. * This function removes a single client from a list of workspaces
  1848. *
  1849. * Inputs:
  1850. * ------
  1851. * pCD = pointer to client data
  1852. * pIDs = pointer to a list of workspace IDs
  1853. * numIDs = number of workspace IDs
  1854. *
  1855. * Outputs:
  1856. * -------
  1857. *
  1858. *************************************<->***********************************/
  1859. void
  1860. RemoveSingleClientFromWorkspaces(
  1861. ClientData *pCD,
  1862. WorkspaceID *pIDs,
  1863. unsigned int numIDs )
  1864. {
  1865. int i;
  1866. WmWorkspaceData *pWS;
  1867. for (i=0; i < numIDs; i++)
  1868. {
  1869. /*
  1870. * Remove the client from the specified workspaces
  1871. */
  1872. if ((pWS = GetWorkspaceData (pCD->pSD, pIDs[i])) &&
  1873. (ClientInWorkspace (pWS, pCD)))
  1874. {
  1875. /*
  1876. * If this workspace is active, then make the
  1877. * window unseen. We only need to call
  1878. * SetClientState on the main window, the
  1879. * transients will get taken care of in there.
  1880. */
  1881. if ((pWS == pCD->pSD->pActiveWS) &&
  1882. (pCD->transientLeader == NULL) &&
  1883. !(pCD->clientState & UNSEEN_STATE))
  1884. {
  1885. SetClientState (pCD,
  1886. (pCD->clientState | UNSEEN_STATE), CurrentTime);
  1887. }
  1888. TakeClientOutOfWorkspace (pWS, pCD);
  1889. /*
  1890. * Update the presence property
  1891. */
  1892. UpdateWorkspacePresenceProperty (pCD);
  1893. }
  1894. }
  1895. } /* END OF FUNCTION RemoveSingleClientFromWorkspaces */
  1896. /*************************************<->*************************************
  1897. *
  1898. * RemoveSubtreeFromWorkspaces (pCD, pIDs, numIDs)
  1899. *
  1900. *
  1901. * Description:
  1902. * -----------
  1903. * This function removes a transient subtree from a list of workspaces
  1904. *
  1905. * Inputs:
  1906. * ------
  1907. * pCD = pointer to client data
  1908. * pIDs = pointer to a list of workspace IDs
  1909. * numIDs = number of workspace IDs
  1910. *
  1911. * Outputs:
  1912. * -------
  1913. *
  1914. *************************************<->***********************************/
  1915. void
  1916. RemoveSubtreeFromWorkspaces(
  1917. ClientData *pCD,
  1918. WorkspaceID *pIDs,
  1919. unsigned int numIDs )
  1920. {
  1921. ClientData *pNext;
  1922. pNext = pCD->transientChildren;
  1923. while (pNext)
  1924. {
  1925. /* process all children first */
  1926. if (pNext->transientChildren)
  1927. {
  1928. RemoveSubtreeFromWorkspaces (pNext, pIDs, numIDs);
  1929. }
  1930. else
  1931. {
  1932. RemoveSingleClientFromWorkspaces (pNext, pIDs, numIDs);
  1933. }
  1934. pNext = pNext->transientSiblings;
  1935. }
  1936. /* process the primary window */
  1937. RemoveSingleClientFromWorkspaces (pCD, pIDs, numIDs);
  1938. } /* END OF FUNCTION RemoveSubtreeFromWorkspaces */
  1939. /******************************<->*************************************
  1940. *
  1941. * pIDs = GetListOfOccupiedWorkspaces (pCD, numIDs)
  1942. *
  1943. *
  1944. * Description:
  1945. * -----------
  1946. * This function creates a list of occupied workspaces of a particular
  1947. * client, EXCLUDING the current workspace.
  1948. *
  1949. * Inputs:
  1950. * ------
  1951. * pCD = pointer to client data
  1952. *
  1953. * Outputs:
  1954. * -------
  1955. * pIDs = pointer to a list of workspace IDs
  1956. * numIDs = number of workspace IDs
  1957. *
  1958. * Comment
  1959. * -------
  1960. * memory for pIDs is allocated with XtMalloc and should be
  1961. * freed with XtFree.
  1962. *
  1963. *
  1964. ******************************<->***********************************/
  1965. WorkspaceID *
  1966. GetListOfOccupiedWorkspaces(
  1967. ClientData *pCD,
  1968. int *numIDs )
  1969. {
  1970. int i;
  1971. WorkspaceID *pLocalIDs = NULL;
  1972. WorkspaceID activeWsID = pCD->pSD->pActiveWS->id;
  1973. *numIDs = 0;
  1974. if ((pLocalIDs = (WorkspaceID *) XtMalloc (pCD->numInhabited *
  1975. sizeof(WorkspaceID))) == NULL)
  1976. {
  1977. Warning (((char *)GETMESSAGE(76, 7, "Insufficient memory")));
  1978. return (NULL);
  1979. }
  1980. for (i = 0; i < pCD->numInhabited; i++)
  1981. {
  1982. if (activeWsID != pCD->pWsList[i].wsID)
  1983. {
  1984. pLocalIDs[(*numIDs)++] = pCD->pWsList[i].wsID;
  1985. }
  1986. }
  1987. return(pLocalIDs);
  1988. } /* END OF FUNCTION GetListOfOccupiedWorkspaces */
  1989. /******************************<->*************************************
  1990. *
  1991. * HonorAbsentMapBehavior(pCD)
  1992. *
  1993. *
  1994. * Description:
  1995. * -----------
  1996. * This function adds a client to the current workspace and
  1997. * if (pCD->absentMapBehavior == AMAP_BEHAVIOR_MOVE)
  1998. * removes the client from the other workspaces
  1999. *
  2000. *
  2001. * Inputs:
  2002. * ------
  2003. * pCD = pointer to client data
  2004. *
  2005. * Outputs:
  2006. * -------
  2007. *
  2008. ******************************<->***********************************/
  2009. void
  2010. HonorAbsentMapBehavior(
  2011. ClientData *pCD)
  2012. {
  2013. int inWorkspace = 0;
  2014. if (pCD->absentMapBehavior == AMAP_BEHAVIOR_MOVE)
  2015. {
  2016. int wsCnt;
  2017. /*
  2018. * Remove from other workspaces
  2019. */
  2020. for (wsCnt = 0; wsCnt < pCD->numInhabited; wsCnt = inWorkspace)
  2021. {
  2022. if (pCD->pWsList[wsCnt].wsID != pCD->pSD->pActiveWS->id)
  2023. {
  2024. RemoveClientFromWorkspaces (pCD,
  2025. &pCD->pWsList[wsCnt].wsID, 1);
  2026. }
  2027. else inWorkspace++;
  2028. }
  2029. }
  2030. if (inWorkspace == 0)
  2031. AddClientToWorkspaces (pCD, &ACTIVE_WS->id, 1);
  2032. } /* END OF FUNCTION HonorAbsentMapBehavior */
  2033. /******************************<->*************************************
  2034. *
  2035. * RemoveClientFromWorkspaces (pCD, pIDs, numIDs)
  2036. *
  2037. *
  2038. * Description:
  2039. * -----------
  2040. * This function removes a client from a list of workspaces
  2041. *
  2042. * Inputs:
  2043. * ------
  2044. * pCD = pointer to client data
  2045. * pIDs = pointer to a list of workspace IDs
  2046. * numIDs = number of workspace IDs
  2047. *
  2048. * Outputs:
  2049. * -------
  2050. *
  2051. ******************************<->***********************************/
  2052. void
  2053. RemoveClientFromWorkspaces(
  2054. ClientData *pCD,
  2055. WorkspaceID *pIDs,
  2056. unsigned int numIDs )
  2057. {
  2058. ClientData *pcdLeader;
  2059. pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
  2060. RemoveSubtreeFromWorkspaces (pcdLeader, pIDs, numIDs);
  2061. } /* END OF FUNCTION RemoveClientFromWorkspaces */
  2062. /*************************************<->*************************************
  2063. *
  2064. * AddSingleClientToWorkspaces (pCD, pIDs, numIDs)
  2065. *
  2066. *
  2067. * Description:
  2068. * -----------
  2069. * This function adds a single client to a list of workspaces
  2070. *
  2071. * Inputs:
  2072. * ------
  2073. * pCD = pointer to client data
  2074. * pIDs = pointer to a list of workspace IDs
  2075. * numIDs = number of workspace IDs
  2076. *
  2077. * Outputs:
  2078. * -------
  2079. *
  2080. *************************************<->***********************************/
  2081. void
  2082. AddSingleClientToWorkspaces(
  2083. ClientData *pCD,
  2084. WorkspaceID *pIDs,
  2085. unsigned int numIDs )
  2086. {
  2087. int i;
  2088. WmWorkspaceData *pWS;
  2089. for (i=0; i < numIDs; i++)
  2090. {
  2091. /*
  2092. * Add the client to the specified workspaces if
  2093. * it is not already there.
  2094. */
  2095. if ((pWS = GetWorkspaceData (pCD->pSD, pIDs[i])) &&
  2096. (!ClientInWorkspace (pWS, pCD)))
  2097. {
  2098. PutClientIntoWorkspace (pWS, pCD);
  2099. if ((pWS == PSD_FOR_CLIENT(pCD)->pActiveWS) &&
  2100. (pCD->transientLeader == NULL) &&
  2101. (pCD->clientState & UNSEEN_STATE))
  2102. {
  2103. SetClientState (pCD,
  2104. (pCD->clientState & ~UNSEEN_STATE), CurrentTime);
  2105. }
  2106. /*
  2107. * Update the presence property (only on transient leader)
  2108. */
  2109. UpdateWorkspacePresenceProperty (pCD);
  2110. }
  2111. }
  2112. } /* END OF FUNCTION AddSingleClientToWorkspace */
  2113. /*************************************<->*************************************
  2114. *
  2115. * AddSubtreeToWorkspaces (pCD, pIDs, numIDs)
  2116. *
  2117. *
  2118. * Description:
  2119. * -----------
  2120. * This function adds a client subtree to a list of workspaces
  2121. *
  2122. * Inputs:
  2123. * ------
  2124. * pCD = pointer to client data (head of subtree)
  2125. * pIDs = pointer to a list of workspace IDs
  2126. * numIDs = number of workspace IDs
  2127. *
  2128. * Outputs:
  2129. * -------
  2130. *
  2131. *************************************<->***********************************/
  2132. void
  2133. AddSubtreeToWorkspaces(
  2134. ClientData *pCD,
  2135. WorkspaceID *pIDs,
  2136. unsigned int numIDs )
  2137. {
  2138. ClientData *pNext;
  2139. pNext = pCD->transientChildren;
  2140. while (pNext)
  2141. {
  2142. /* process all children first */
  2143. if (pNext->transientChildren)
  2144. {
  2145. AddSubtreeToWorkspaces (pNext, pIDs, numIDs);
  2146. }
  2147. else
  2148. {
  2149. AddSingleClientToWorkspaces (pNext, pIDs, numIDs);
  2150. }
  2151. pNext = pNext->transientSiblings;
  2152. }
  2153. /* process the primary window */
  2154. AddSingleClientToWorkspaces (pCD, pIDs, numIDs);
  2155. } /* END OF FUNCTION AddSubtreeToWorkspaces */
  2156. /*************************************<->*************************************
  2157. *
  2158. * AddClientToWorkspaces (pCD, pIDs, numIDs)
  2159. *
  2160. *
  2161. * Description:
  2162. * -----------
  2163. * This function adds a transient tree to a list of workspaces
  2164. *
  2165. * Inputs:
  2166. * ------
  2167. * pCD = pointer to client data
  2168. * pIDs = pointer to a list of workspace IDs
  2169. * numIDs = number of workspace IDs
  2170. *
  2171. * Outputs:
  2172. * -------
  2173. *
  2174. *************************************<->***********************************/
  2175. void
  2176. AddClientToWorkspaces(
  2177. ClientData *pCD,
  2178. WorkspaceID *pIDs,
  2179. unsigned int numIDs )
  2180. {
  2181. ClientData *pcdLeader;
  2182. pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
  2183. AddSubtreeToWorkspaces (pcdLeader, pIDs, numIDs);
  2184. } /* END OF FUNCTION AddClientToWorkspaces */
  2185. /*************************************<->*************************************
  2186. *
  2187. * AddClientToWsList (pWS, pCD)
  2188. *
  2189. *
  2190. * Description:
  2191. * -----------
  2192. * This function adds a client to a list of clients in a workspace
  2193. *
  2194. * Inputs:
  2195. * ------
  2196. * pCD = pointer to client data
  2197. * pWS = pointer to workspace data
  2198. *
  2199. * Outputs:
  2200. * -------
  2201. * none
  2202. *
  2203. *************************************<->***********************************/
  2204. void
  2205. AddClientToWsList(
  2206. WmWorkspaceData *pWS,
  2207. ClientData *pCD )
  2208. {
  2209. if (pWS->numClients >= pWS->sizeClientList)
  2210. {
  2211. if (pWS->sizeClientList == 0)
  2212. {
  2213. pWS->ppClients = (ClientData **)
  2214. XtMalloc (WINDOW_ALLOC_AMOUNT * sizeof(ClientData *));
  2215. }
  2216. else
  2217. {
  2218. pWS->ppClients = (ClientData **)
  2219. XtRealloc ((char *)pWS->ppClients,
  2220. (pWS->sizeClientList + WINDOW_ALLOC_AMOUNT) *
  2221. sizeof(ClientData *));
  2222. }
  2223. if (!pWS->ppClients)
  2224. {
  2225. Warning (((char *)GETMESSAGE(76, 9, "Insufficient memory to add window to workspace")));
  2226. ExitWM(WM_ERROR_EXIT_VALUE);
  2227. }
  2228. pWS->sizeClientList += WINDOW_ALLOC_AMOUNT;
  2229. }
  2230. if (pWS->numClients < pWS->sizeClientList)
  2231. {
  2232. pWS->ppClients[pWS->numClients] = pCD;
  2233. pWS->numClients++;
  2234. }
  2235. } /* END OF FUNCTION AddClientToWsList */
  2236. /*************************************<->*************************************
  2237. *
  2238. * RemoveClientFromWsList (pWS, pCD)
  2239. *
  2240. *
  2241. * Description:
  2242. * -----------
  2243. * This function removes a client from a list of clients in a workspace
  2244. *
  2245. * Inputs:
  2246. * ------
  2247. * pCD = pointer to client data
  2248. * pWS = pointer to workspace data
  2249. *
  2250. * Outputs:
  2251. * -------
  2252. * none
  2253. *
  2254. *************************************<->***********************************/
  2255. void
  2256. RemoveClientFromWsList(
  2257. WmWorkspaceData *pWS,
  2258. ClientData *pCD )
  2259. {
  2260. int src, dest;
  2261. for (dest = 0; dest < pWS->numClients; dest++)
  2262. {
  2263. if (pWS->ppClients[dest] == pCD)
  2264. {
  2265. break;
  2266. }
  2267. }
  2268. for (src = dest+1; src < pWS->numClients; src++, dest++)
  2269. {
  2270. pWS->ppClients[dest] = pWS->ppClients[src];
  2271. }
  2272. pWS->numClients--;
  2273. } /* END OF FUNCTION RemoveClientFromWsList */
  2274. /*************************************<->*************************************
  2275. *
  2276. * Boolean
  2277. * F_CreateWorkspace (args, pCD, event)
  2278. *
  2279. * Description:
  2280. * -----------
  2281. *
  2282. * Inputs:
  2283. * ------
  2284. * args = ...
  2285. * pCD = ...
  2286. * event = ...
  2287. *
  2288. * Outputs:
  2289. * -------
  2290. * Return = ...
  2291. *
  2292. * Comments:
  2293. * --------
  2294. *
  2295. *************************************<->***********************************/
  2296. Boolean
  2297. F_CreateWorkspace(
  2298. String args,
  2299. ClientData *pCD,
  2300. XEvent *event )
  2301. {
  2302. WmScreenData *pSD = ACTIVE_PSD;
  2303. if (pSD->numWorkspaces >= MAX_WORKSPACE_COUNT)
  2304. {
  2305. char buffer[MAXWMPATH];
  2306. /*
  2307. * At the maximum number of allowed workspaces.
  2308. */
  2309. sprintf (buffer,
  2310. ((char *)GETMESSAGE(76, 14, "Maximum number of workspaces is %d. New workspace was not created.")), MAX_WORKSPACE_COUNT);
  2311. Warning (buffer);
  2312. }
  2313. else
  2314. {
  2315. CreateWorkspace (ACTIVE_PSD, (unsigned char *)args);
  2316. }
  2317. return (TRUE);
  2318. } /* END OF FUNCTION F_CreateWorkspace */
  2319. /*************************************<->*************************************
  2320. *
  2321. * Boolean
  2322. * F_DeleteWorkspace (args, pCD, event)
  2323. *
  2324. * Description:
  2325. * -----------
  2326. *
  2327. * Inputs:
  2328. * ------
  2329. * args = ...
  2330. * pCD = ...
  2331. * event = ...
  2332. *
  2333. * Outputs:
  2334. * -------
  2335. * Return = ...
  2336. *
  2337. * Comments:
  2338. * --------
  2339. *
  2340. *************************************<->***********************************/
  2341. Boolean
  2342. F_DeleteWorkspace(
  2343. String args,
  2344. ClientData *pCD,
  2345. XEvent *event )
  2346. {
  2347. WmScreenData *pSD = ACTIVE_PSD;
  2348. WmWorkspaceData *pWS = NULL;
  2349. int i;
  2350. if (args == NULL)
  2351. {
  2352. pWS= ACTIVE_WS;
  2353. }
  2354. else
  2355. {
  2356. for (i=0; i<pSD->numWorkspaces; i++)
  2357. {
  2358. if (!strcmp(pSD->pWS[i].name, args))
  2359. {
  2360. pWS = &(pSD->pWS[i]);
  2361. break;
  2362. }
  2363. }
  2364. }
  2365. if (pWS)
  2366. DeleteWorkspace (pWS);
  2367. return (TRUE);
  2368. } /* END OF FUNCTION F_DeleteWorkspace */
  2369. /*************************************<->*************************************
  2370. *
  2371. * Boolean
  2372. * F_GotoWorkspace (args, pCD, event)
  2373. *
  2374. * Description:
  2375. * -----------
  2376. *
  2377. * Inputs:
  2378. * ------
  2379. * args = ...
  2380. * pCD = ...
  2381. * event = ...
  2382. *
  2383. * Outputs:
  2384. * -------
  2385. * Return = ...
  2386. *
  2387. * Comments:
  2388. * --------
  2389. *
  2390. *************************************<->***********************************/
  2391. Boolean
  2392. F_GotoWorkspace(
  2393. String args,
  2394. ClientData *pCD,
  2395. XEvent *event )
  2396. {
  2397. WorkspaceID wsID;
  2398. WmWorkspaceData *pWS;
  2399. wsID = XInternAtom (DISPLAY, args, False);
  2400. pWS = GetWorkspaceData (ACTIVE_PSD, wsID);
  2401. if (pWS)
  2402. {
  2403. ChangeToWorkspace (pWS);
  2404. }
  2405. return (TRUE);
  2406. } /* END OF FUNCTION F_GotoWorkspace */
  2407. /*************************************<->*************************************
  2408. *
  2409. * Boolean
  2410. * F_AddToAllWorkspaces (args, pCD, event)
  2411. *
  2412. *
  2413. * Description:
  2414. * -----------
  2415. * Puts a client into all workspaces
  2416. *
  2417. *
  2418. * Inputs:
  2419. * ------
  2420. * args = ...
  2421. * pCD = pointer to client data
  2422. * event = ...
  2423. *
  2424. *
  2425. * Outputs:
  2426. * -------
  2427. * Return = True
  2428. *
  2429. *
  2430. * Comments:
  2431. * --------
  2432. * The list of Ids returned has been privately allocated. Copy
  2433. * if you want to save or do anything with it.
  2434. *
  2435. *************************************<->***********************************/
  2436. Boolean
  2437. F_AddToAllWorkspaces(
  2438. String args,
  2439. ClientData *pCD,
  2440. XEvent *event )
  2441. {
  2442. WmScreenData *pSD;
  2443. int i;
  2444. if (pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS))
  2445. {
  2446. pSD = pCD->pSD;
  2447. ReserveIdListSpace (pSD->numWorkspaces);
  2448. for (i = 0; i < pSD->numWorkspaces; i++)
  2449. {
  2450. pResIDs[i] = pSD->pWS[i].id;
  2451. }
  2452. AddClientToWorkspaces (pCD, pResIDs, pSD->numWorkspaces);
  2453. pCD->putInAll = True;
  2454. }
  2455. return (True);
  2456. } /* END OF FUNCTION F_AddToAllWorkspaces */
  2457. /*************************************<->*************************************
  2458. *
  2459. * Boolean
  2460. * F_Remove (args, pCD, event)
  2461. *
  2462. *
  2463. * Description:
  2464. * -----------
  2465. * Removes a client from the current workspace
  2466. *
  2467. *
  2468. * Inputs:
  2469. * ------
  2470. * args = ...
  2471. * pCD = pointer to client data
  2472. * event = ...
  2473. *
  2474. *
  2475. * Outputs:
  2476. * -------
  2477. * Return = True
  2478. *
  2479. *
  2480. * Comments:
  2481. * --------
  2482. *
  2483. *************************************<->***********************************/
  2484. Boolean
  2485. F_Remove(
  2486. String args,
  2487. ClientData *pCD,
  2488. XEvent *event )
  2489. {
  2490. Boolean rval = False;
  2491. /*
  2492. * Only remove if in more than one workspace.
  2493. */
  2494. if ((pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS)) &&
  2495. (pCD->numInhabited > 1))
  2496. {
  2497. if (ClientInWorkspace (ACTIVE_WS, pCD))
  2498. {
  2499. RemoveClientFromWorkspaces (pCD, &ACTIVE_WS->id, 1);
  2500. pCD->putInAll = False;
  2501. }
  2502. }
  2503. return (rval);
  2504. } /* END OF FUNCTION F_Remove */
  2505. /*************************************<->*************************************
  2506. *
  2507. * GetCurrentWorkspaceIndex (pSD)
  2508. *
  2509. *
  2510. * Description:
  2511. * -----------
  2512. * Returns an index into the screens array of workspace structures
  2513. * for the current workspace.
  2514. *
  2515. *
  2516. * Inputs:
  2517. * ------
  2518. *
  2519. *
  2520. * Outputs:
  2521. * -------
  2522. *
  2523. *
  2524. * Comments:
  2525. * --------
  2526. *************************************<->***********************************/
  2527. int
  2528. GetCurrentWorkspaceIndex(
  2529. WmScreenData *pSD )
  2530. {
  2531. int i;
  2532. for (i = 0 ; i < pSD->numWorkspaces; i++)
  2533. {
  2534. if (pSD->pWS[i].id == pSD->pActiveWS->id)
  2535. break;
  2536. }
  2537. if (i >= pSD->numWorkspaces)
  2538. {
  2539. /* failed to find workspace!!! How did that happen??? */
  2540. i = 0;
  2541. #ifdef DEBUG
  2542. Warning ("Failed to find workspace index");
  2543. #endif /* DEBUG */
  2544. }
  2545. return(i);
  2546. } /* END OF FUNCTION GetCurrentWorkspaceIndex */
  2547. /*************************************<->*************************************
  2548. *
  2549. * void
  2550. * InsureIconForWorkspace (pWS, pCD)
  2551. *
  2552. *
  2553. * Description:
  2554. * -----------
  2555. * Makes sure an icon exists for the workspace
  2556. *
  2557. *
  2558. * Inputs:
  2559. * ------
  2560. *
  2561. *
  2562. * Outputs:
  2563. * -------
  2564. *
  2565. * Comments:
  2566. * --------
  2567. *
  2568. *************************************<->***********************************/
  2569. void
  2570. InsureIconForWorkspace(
  2571. WmWorkspaceData *pWS,
  2572. ClientData *pCD )
  2573. {
  2574. WsClientData *pWsc;
  2575. if (pCD->clientFunctions & MWM_FUNC_MINIMIZE)
  2576. {
  2577. pWsc = GetWsClientData (pWS, pCD);
  2578. if ((pCD->pSD->useIconBox) &&
  2579. (!(pCD->clientFlags & (CLIENT_WM_CLIENTS | FRONT_PANEL_BOX))))
  2580. {
  2581. /*
  2582. * Create a new widget for the icon box
  2583. */
  2584. if (MakeIcon (pWS, pCD))
  2585. {
  2586. XSaveContext (DISPLAY, pWsc->iconFrameWin,
  2587. wmGD.windowContextType, (caddr_t)pCD);
  2588. if (pCD->iconWindow && pWsc->iconFrameWin)
  2589. {
  2590. XGrabButton (DISPLAY, AnyButton, AnyModifier,
  2591. pWsc->iconFrameWin, True,
  2592. ButtonPressMask|ButtonReleaseMask|
  2593. ButtonMotionMask,
  2594. GrabModeAsync, GrabModeAsync, None,
  2595. wmGD.workspaceCursor);
  2596. }
  2597. ShowClientIconState (pCD, (pCD->clientState & ~UNSEEN_STATE));
  2598. }
  2599. }
  2600. else
  2601. {
  2602. /*
  2603. * Reuse existing icon in new workspaces. Suggest
  2604. * icon position in current WS as position of icon
  2605. * in new WS.
  2606. */
  2607. pWsc->iconFrameWin = pCD->pWsList[0].iconFrameWin;
  2608. pWsc->iconX = ICON_X(pCD);
  2609. pWsc->iconY = ICON_Y(pCD);
  2610. if ((pCD->clientState & ~UNSEEN_STATE) != MINIMIZED_STATE)
  2611. {
  2612. pWsc->iconPlace = NO_ICON_PLACE;
  2613. }
  2614. else if (!wmGD.iconAutoPlace)
  2615. {
  2616. if (wmGD.positionIsFrame)
  2617. {
  2618. pWsc->iconX -= pCD->clientOffset.x;
  2619. pWsc->iconY -= pCD->clientOffset.y;
  2620. }
  2621. PlaceIconOnScreen (pCD, &pWsc->iconX, &pWsc->iconY);
  2622. }
  2623. else /* icon auto placement */
  2624. {
  2625. pWsc->iconPlace =
  2626. CvtIconPositionToPlace (&pWS->IPData,
  2627. pWsc->iconX, pWsc->iconY);
  2628. if (pWS->IPData.placeList[pWsc->iconPlace].pCD)
  2629. {
  2630. /* The spot is already occupied! Find a
  2631. spot nearby. */
  2632. pWsc->iconPlace =
  2633. FindIconPlace (pCD, &pWS->IPData, pWsc->iconX,
  2634. pWsc->iconY);
  2635. if (pWsc->iconPlace == NO_ICON_PLACE)
  2636. {
  2637. /* Can't find a spot close by. Use the
  2638. next available slot */
  2639. pWsc->iconPlace = GetNextIconPlace (&pWS->IPData);
  2640. if (pWsc->iconPlace == NO_ICON_PLACE)
  2641. {
  2642. pWsc->iconPlace =
  2643. CvtIconPositionToPlace (&pWS->IPData,
  2644. pCD->clientX,
  2645. pCD->clientY);
  2646. }
  2647. }
  2648. }
  2649. CvtIconPlaceToPosition (&pWS->IPData, pWsc->iconPlace,
  2650. &pWsc->iconX, &pWsc->iconY);
  2651. if (!(pWS->IPData.placeList[pWsc->iconPlace].pCD))
  2652. {
  2653. pWS->IPData.placeList[pWsc->iconPlace].pCD = pCD;
  2654. }
  2655. }
  2656. }
  2657. }
  2658. } /* END OF FUNCTION InsureIconForWorkspace */
  2659. /*************************************<->*************************************
  2660. *
  2661. * Boolean
  2662. * GetLeaderPresence (pCD, pIDs, pnumIDs)
  2663. *
  2664. *
  2665. * Description:
  2666. * -----------
  2667. * Gets the workspace presence of the transient tree leader for a
  2668. * client.
  2669. *
  2670. *
  2671. * Inputs:
  2672. * ------
  2673. * pCD = pointer to client data
  2674. * ppIDs = pointer to pointer to list of workspace ids
  2675. * pnumIDs = pointer to number of workspace ids
  2676. *
  2677. *
  2678. * Outputs:
  2679. * -------
  2680. * *ppIDS = list of workspace IDs
  2681. * *pnumIDs = number of workspace IDs in list
  2682. *
  2683. * Return = true on success
  2684. *
  2685. *
  2686. * Comments:
  2687. * --------
  2688. * ID list is dynamically allocated, please XtFree() it when you're
  2689. * done.
  2690. *
  2691. *************************************<->***********************************/
  2692. Boolean
  2693. GetLeaderPresence(
  2694. ClientData *pCD,
  2695. WorkspaceID **ppIDs,
  2696. unsigned int *pnumIDs )
  2697. {
  2698. ClientData *pcdLeader;
  2699. int i;
  2700. Boolean rval = False;
  2701. WorkspaceID *pLocalIDs;
  2702. if ((pLocalIDs = (WorkspaceID *) XtMalloc (pCD->pSD->numWorkspaces *
  2703. sizeof(WorkspaceID))) == NULL)
  2704. {
  2705. Warning (((char *)GETMESSAGE(76, 10, "Insufficient Memory (GetLeaderPresence)")));
  2706. ExitWM (WM_ERROR_EXIT_VALUE);
  2707. }
  2708. /*
  2709. * Make up list of workspaces for primary window
  2710. */
  2711. if (pCD->transientLeader)
  2712. {
  2713. pcdLeader = FindTransientTreeLeader (pCD);
  2714. for (i = 0; i < pcdLeader->numInhabited; i++)
  2715. {
  2716. pLocalIDs[i] = pcdLeader->pWsList[i].wsID;
  2717. }
  2718. *ppIDs = pLocalIDs;
  2719. *pnumIDs = pcdLeader->numInhabited;
  2720. rval = True;
  2721. }
  2722. return (rval);
  2723. } /* END OF FUNCTION GetLeaderPresence */
  2724. /*************************************<->*************************************
  2725. *
  2726. * Boolean
  2727. * GetMyOwnPresence (pCD, pIDs, pnumIDs)
  2728. *
  2729. *
  2730. * Description:
  2731. * -----------
  2732. * Returns the current workspace presence for the client
  2733. *
  2734. *
  2735. * Inputs:
  2736. * ------
  2737. * pCD = pointer to client data
  2738. * ppIDs = pointer to pointer to list of workspace ids
  2739. * pnumIDs = pointer to number of workspace ids
  2740. *
  2741. *
  2742. * Outputs:
  2743. * -------
  2744. * *ppIDS = list of workspace IDs
  2745. * *pnumIDs = number of workspace IDs in list
  2746. *
  2747. * Return = true on success
  2748. *
  2749. *
  2750. * Comments:
  2751. * --------
  2752. * ID list is dynamically allocated (by DtWsmGetWorkspacesOccupied).
  2753. * Please XtFree() it when you're done.
  2754. *
  2755. *************************************<->***********************************/
  2756. Boolean
  2757. GetMyOwnPresence(
  2758. ClientData *pCD,
  2759. WorkspaceID **ppIDs,
  2760. unsigned int *pnumIDs )
  2761. {
  2762. Boolean rval = False;
  2763. unsigned long nIDs = (unsigned long)*pnumIDs;
  2764. /*
  2765. * Get the workspace presence property
  2766. */
  2767. if (
  2768. HasProperty (pCD, wmGD.xa_DT_WORKSPACE_PRESENCE)
  2769. && (DtWsmGetWorkspacesOccupied (DISPLAY, pCD->client, ppIDs,
  2770. &nIDs) == Success))
  2771. {
  2772. if (nIDs)
  2773. {
  2774. rval = True;
  2775. }
  2776. }
  2777. *pnumIDs = (unsigned int)nIDs;
  2778. return (rval);
  2779. } /* END OF FUNCTION GetMyOwnPresence */
  2780. /*************************************<->*************************************
  2781. *
  2782. * void
  2783. * ReserveIdListSpace (numIDs)
  2784. *
  2785. *
  2786. * Description:
  2787. * -----------
  2788. * Insures that there is enough room in our privately allocated
  2789. * list of workspace IDs
  2790. *
  2791. *
  2792. * Inputs:
  2793. * ------
  2794. * numIDs = number of workspace ids
  2795. *
  2796. * Outputs:
  2797. * -------
  2798. *
  2799. * Comments:
  2800. * --------
  2801. *************************************<->***********************************/
  2802. void
  2803. ReserveIdListSpace(
  2804. int numIDs )
  2805. {
  2806. if (numResIDs == 0)
  2807. {
  2808. pResIDs = (WorkspaceID *)
  2809. XtMalloc (numIDs * sizeof (WorkspaceID));
  2810. if (pResIDs)
  2811. {
  2812. numResIDs = numIDs;
  2813. }
  2814. }
  2815. else if (numResIDs < numIDs)
  2816. {
  2817. pResIDs = (WorkspaceID *) XtRealloc ((char *)pResIDs,
  2818. numIDs * sizeof (WorkspaceID));
  2819. numResIDs = (pResIDs)? numIDs : 0;
  2820. }
  2821. if (pResIDs == NULL)
  2822. {
  2823. Warning (((char *)GETMESSAGE(76, 11, "Insufficient memory")));
  2824. ExitWM (WM_ERROR_EXIT_VALUE);
  2825. }
  2826. } /* END OF FUNCTION ReserveIdListSpace */
  2827. /******************************<->*************************************
  2828. *
  2829. * SaveResources (pSD)
  2830. *
  2831. * Description:
  2832. * -----------
  2833. * Saves dtwm resources to restore session
  2834. *
  2835. * Inputs:
  2836. * ------
  2837. * pSD = pointer to screen data
  2838. *
  2839. * Outputs:
  2840. * -------
  2841. * None
  2842. *
  2843. * Comments:
  2844. * ---------
  2845. *
  2846. *************************************<->***********************************/
  2847. void
  2848. SaveResources( WmScreenData *pSD)
  2849. {
  2850. int wsCnt;
  2851. WmPanelistObject pPanelist;
  2852. if(pSD)
  2853. {
  2854. if (pSD->pActiveWS)
  2855. {
  2856. SaveWorkspaceResources(pSD->pActiveWS,
  2857. (WM_RES_INITIAL_WORKSPACE |
  2858. WM_RES_WORKSPACE_COUNT));
  2859. }
  2860. pPanelist = (WmPanelistObject) pSD->wPanelist;
  2861. if (pPanelist && O_Shell(pPanelist))
  2862. {
  2863. /* This is the front panel for the screen */
  2864. SaveWorkspaceResources(pSD->pActiveWS,
  2865. WM_RES_FP_POSITION);
  2866. /* Call the fronto panel function to save its resources */
  2867. WmFrontPanelSessionSaveData();
  2868. }
  2869. for (wsCnt = 0; wsCnt < pSD->numWorkspaces; wsCnt++)
  2870. {
  2871. if(pSD->useIconBox)
  2872. {
  2873. SaveWorkspaceResources(&pSD->pWS[wsCnt],
  2874. WM_RES_ICONBOX_GEOMETRY);
  2875. }
  2876. } /* for wsCnt */
  2877. SaveHelpResources(pSD);
  2878. } /* if pSD */
  2879. } /* END OF FUNCTION SaveResources */
  2880. /******************************<->*************************************
  2881. *
  2882. * SaveWorkspaceResource (pWS, flags)
  2883. *
  2884. * Description:
  2885. * -----------
  2886. * Modifies the RESOURCE_MANAGER property to add update versions
  2887. * of the requested resources.
  2888. *
  2889. * Inputs:
  2890. * ------
  2891. * pWS = pointer to workspace data
  2892. *
  2893. * Outputs:
  2894. * -------
  2895. * None
  2896. *
  2897. * Comments:
  2898. * ---------
  2899. *
  2900. *************************************<->***********************************/
  2901. void
  2902. SaveWorkspaceResources(
  2903. WmWorkspaceData *pWS,
  2904. unsigned long flags)
  2905. {
  2906. char *buffer = NULL;
  2907. int bufferLength = 0;
  2908. char *res_class;
  2909. char *data;
  2910. int cum_len;
  2911. char screenName[1024];
  2912. char tmpScreenName[10];
  2913. Position clientX;
  2914. Position clientY;
  2915. Dimension clientWidth;
  2916. Dimension clientHeight;
  2917. int xoff, yoff;
  2918. WmPanelistObject pPanelist = (WmPanelistObject) pWS->pSD->wPanelist;
  2919. ClientData *pCD_Panel ;
  2920. char tmpBuffer[MAXWMPATH+1];
  2921. int iLen;
  2922. /* allocate initial data space */
  2923. if ((data = (char *) XtMalloc (MAXWMPATH+1)) == NULL)
  2924. {
  2925. Warning (((char *)
  2926. GETMESSAGE(76,12,"Insufficient memory to save resources")));
  2927. Do_Quit_Mwm (False);
  2928. }
  2929. cum_len = 1;
  2930. *data = '\0';
  2931. if (bufferLength == 0)
  2932. {
  2933. buffer = (char *) XtMalloc (MAXWMPATH+1);
  2934. bufferLength = MAXWMPATH;
  2935. }
  2936. *buffer = '\0';
  2937. /* Get our current resource class */
  2938. if (MwmBehavior)
  2939. {
  2940. res_class = WM_RESOURCE_CLASS;
  2941. }
  2942. else
  2943. {
  2944. res_class = DT_WM_RESOURCE_CLASS;
  2945. }
  2946. strcpy(screenName, "*");
  2947. strcat(screenName,XtName (pWS->pSD->screenTopLevelW));
  2948. /* construct and write out the resources specification */
  2949. if (flags & WM_RES_BACKDROP_IMAGE)
  2950. {
  2951. iLen = (strlen (res_class) + strlen (screenName) +
  2952. strlen (pWS->name) + strlen (WmNbackdrop) +
  2953. strlen (WmNimage) + strlen (pWS->backdrop.image) + 20);
  2954. if (iLen > bufferLength)
  2955. {
  2956. bufferLength += iLen;
  2957. buffer = (char *)
  2958. XtRealloc (buffer, bufferLength * sizeof(char));
  2959. }
  2960. sprintf (buffer, "%s%s*%s*%s*%s: %s\n", res_class,
  2961. screenName, pWS->name,
  2962. WmNbackdrop, WmNimage, pWS->backdrop.image);
  2963. AddStringToResourceData (buffer, &data, &cum_len);
  2964. }
  2965. if (flags & WM_RES_WORKSPACE_TITLE)
  2966. {
  2967. String asciiName;
  2968. asciiName = WmXmStringToString (pWS->title);
  2969. iLen = strlen (res_class) + strlen (screenName) +
  2970. strlen (pWS->name) + strlen (WmNtitle) +
  2971. strlen (asciiName) + 16;
  2972. if (iLen > bufferLength)
  2973. {
  2974. bufferLength += iLen;
  2975. buffer = (char *)
  2976. XtRealloc (buffer, bufferLength * sizeof(char));
  2977. }
  2978. sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
  2979. screenName, pWS->name,
  2980. WmNtitle, asciiName);
  2981. AddStringToResourceData (buffer, &data, &cum_len);
  2982. XtFree (asciiName);
  2983. }
  2984. if ((flags & WM_RES_INITIAL_WORKSPACE) &&
  2985. (!wmGD.useStandardBehavior))
  2986. {
  2987. iLen = strlen (res_class) + strlen (screenName) +
  2988. strlen (WmNinitialWorkspace) + strlen (pWS->name) + 14;
  2989. if (iLen > bufferLength)
  2990. {
  2991. bufferLength += iLen;
  2992. buffer = (char *)
  2993. XtRealloc (buffer, bufferLength * sizeof(char));
  2994. }
  2995. sprintf (buffer, "%s%s*%s: %s\n", res_class,
  2996. screenName,
  2997. WmNinitialWorkspace, pWS->name);
  2998. AddStringToResourceData (buffer, &data, &cum_len);
  2999. }
  3000. if ((flags & WM_RES_WORKSPACE_LIST) &&
  3001. (!wmGD.useStandardBehavior))
  3002. {
  3003. WmWorkspaceData *pWSi;
  3004. char *pchQname;
  3005. int i;
  3006. pWSi = pWS->pSD->pWS;
  3007. pchQname = (char *) _DtWmParseMakeQuotedString (
  3008. (unsigned char *)pWSi->name);
  3009. strcpy ((char *)wmGD.tmpBuffer, pchQname);
  3010. XtFree (pchQname);
  3011. pWSi++;
  3012. for (i=1; i<pWS->pSD->numWorkspaces; i++, pWSi++)
  3013. {
  3014. strcat ((char *)wmGD.tmpBuffer, " ");
  3015. pchQname = (char *) _DtWmParseMakeQuotedString (
  3016. (unsigned char *)pWSi->name);
  3017. strcat ((char *)wmGD.tmpBuffer, pchQname);
  3018. XtFree (pchQname);
  3019. }
  3020. sprintf (buffer, "%s%s*%s: %s\n", res_class,
  3021. screenName,
  3022. WmNworkspaceList, wmGD.tmpBuffer);
  3023. AddStringToResourceData (buffer, &data, &cum_len);
  3024. }
  3025. if ((flags & WM_RES_WORKSPACE_COUNT) &&
  3026. (!wmGD.useStandardBehavior))
  3027. {
  3028. char pchNumWs[20];
  3029. sprintf (pchNumWs, "%d", pWS->pSD->numWorkspaces);
  3030. iLen = strlen (res_class) + strlen (screenName) +
  3031. strlen (WmNworkspaceCount) + strlen (pchNumWs) + 14;
  3032. if (iLen > bufferLength)
  3033. {
  3034. bufferLength += iLen;
  3035. buffer = (char *)
  3036. XtRealloc (buffer, bufferLength * sizeof(char));
  3037. }
  3038. sprintf (buffer, "%s%s*%s: %s\n", res_class,
  3039. screenName,
  3040. WmNworkspaceCount, pchNumWs);
  3041. AddStringToResourceData (buffer, &data, &cum_len);
  3042. }
  3043. if ((flags & WM_RES_FP_POSITION) &&
  3044. (O_Shell(pPanelist)) &&
  3045. (!wmGD.useStandardBehavior) &&
  3046. (!XFindContext (DISPLAY, XtWindow(O_Shell(pPanelist)),
  3047. wmGD.windowContextType,
  3048. (XtPointer)&pCD_Panel)))
  3049. {
  3050. Position midX, midY, tmpX, tmpY;
  3051. Dimension screenWidth, screenHeight;
  3052. clientX = pCD_Panel->clientX;
  3053. clientY = pCD_Panel->clientY;
  3054. /*
  3055. * Determine quadrant that the front panel midpoint is
  3056. * in and save front panel with appropriate gravity.
  3057. */
  3058. /* find panel midpoint */
  3059. midX = clientX+(pCD_Panel->clientWidth >> 1);
  3060. midY = clientY+(pCD_Panel->clientHeight >> 1);
  3061. /* get screen dimensions */
  3062. screenWidth = XDisplayWidth (DISPLAY, pCD_Panel->pSD->screen);
  3063. screenHeight = XDisplayHeight (DISPLAY, pCD_Panel->pSD->screen);
  3064. /*
  3065. * Determine midpoint quadrant and set up client geometry
  3066. * relative to that corner. Adjust if positionIsFrame
  3067. * is being used.
  3068. */
  3069. if (midX <= (Position) screenWidth/2)
  3070. {
  3071. if(wmGD.positionIsFrame)
  3072. {
  3073. clientX -= pCD_Panel->frameInfo.upperBorderWidth;
  3074. }
  3075. /* West */
  3076. if (midY <= (Position) screenHeight/2)
  3077. {
  3078. /* NorthWest */
  3079. if(wmGD.positionIsFrame)
  3080. {
  3081. clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
  3082. pCD_Panel->frameInfo.titleBarHeight);
  3083. }
  3084. sprintf (tmpBuffer, "+%d+%d", clientX, clientY);
  3085. }
  3086. else
  3087. {
  3088. /* SouthWest */
  3089. clientY = screenHeight - clientY - pCD_Panel->clientHeight;
  3090. if(wmGD.positionIsFrame)
  3091. {
  3092. clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
  3093. }
  3094. sprintf (tmpBuffer, "+%d-%d", clientX, clientY);
  3095. }
  3096. }
  3097. else
  3098. {
  3099. clientX = screenWidth - clientX - pCD_Panel->clientWidth;
  3100. if (wmGD.positionIsFrame)
  3101. {
  3102. clientX -= pCD_Panel->frameInfo.lowerBorderWidth;
  3103. }
  3104. /* East */
  3105. if (midY <= (Position) screenHeight/2)
  3106. {
  3107. /* NorthEast */
  3108. if(wmGD.positionIsFrame)
  3109. {
  3110. clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
  3111. pCD_Panel->frameInfo.titleBarHeight);
  3112. }
  3113. sprintf (tmpBuffer, "-%d+%d", clientX, clientY);
  3114. }
  3115. else
  3116. {
  3117. /* SouthEast */
  3118. clientY = screenHeight - clientY - pCD_Panel->clientHeight;
  3119. if(wmGD.positionIsFrame)
  3120. {
  3121. clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
  3122. }
  3123. sprintf (tmpBuffer, "-%d-%d", clientX, clientY);
  3124. }
  3125. }
  3126. iLen = strlen (res_class) + strlen (screenName) +
  3127. strlen (XtName(O_Shell(pPanelist))) +
  3128. strlen (WmNgeometry) + strlen (tmpBuffer) + 18;
  3129. if (iLen > bufferLength)
  3130. {
  3131. bufferLength += iLen;
  3132. buffer = (char *)
  3133. XtRealloc (buffer, bufferLength * sizeof(char));
  3134. }
  3135. sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
  3136. screenName,
  3137. XtName (O_Shell(pPanelist)),
  3138. WmNgeometry, tmpBuffer);
  3139. AddStringToResourceData (buffer, &data, &cum_len);
  3140. }
  3141. if ((flags & WM_RES_ICONBOX_GEOMETRY) &&
  3142. (!wmGD.useStandardBehavior))
  3143. {
  3144. /* update iconbox geometry string */
  3145. if (pWS->iconBoxGeometry)
  3146. {
  3147. XtFree((char *) (pWS->iconBoxGeometry));
  3148. pWS->iconBoxGeometry = NULL;
  3149. }
  3150. clientWidth = (pWS->pIconBox->pCD_iconBox->clientWidth -
  3151. pWS->pIconBox->pCD_iconBox->baseWidth) /
  3152. pWS->pIconBox->pCD_iconBox->widthInc;
  3153. clientHeight = (pWS->pIconBox->pCD_iconBox->clientHeight -
  3154. pWS->pIconBox->pCD_iconBox->baseHeight) /
  3155. pWS->pIconBox->pCD_iconBox->heightInc ;
  3156. if(wmGD.positionIsFrame)
  3157. {
  3158. CalculateGravityOffset (pWS->pIconBox->pCD_iconBox, &xoff, &yoff);
  3159. clientX = pWS->pIconBox->pCD_iconBox->clientX - xoff;
  3160. clientY = pWS->pIconBox->pCD_iconBox->clientY - yoff;
  3161. }
  3162. else
  3163. {
  3164. clientX = pWS->pIconBox->pCD_iconBox->clientX;
  3165. clientY = pWS->pIconBox->pCD_iconBox->clientY;
  3166. }
  3167. sprintf (buffer, "%dx%d+%d+%d", clientWidth, clientHeight,
  3168. clientX, clientY);
  3169. pWS->iconBoxGeometry = strdup( buffer);
  3170. iLen = strlen (res_class) + strlen (screenName) +
  3171. strlen (pWS->name) + strlen (WmNiconBoxGeometry) +
  3172. strlen (pWS->iconBoxGeometry) + 18;
  3173. if (iLen > bufferLength)
  3174. {
  3175. bufferLength += iLen;
  3176. buffer = (char *)
  3177. XtRealloc (buffer, bufferLength * sizeof(char));
  3178. }
  3179. sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
  3180. screenName, pWS->name,
  3181. WmNiconBoxGeometry, pWS->iconBoxGeometry);
  3182. AddStringToResourceData (buffer, &data, &cum_len);
  3183. }
  3184. if (data)
  3185. {
  3186. /*
  3187. * Merge in the resource(s)
  3188. */
  3189. _DtAddToResource (DISPLAY, data);
  3190. XtFree(data);
  3191. }
  3192. XtFree(buffer);
  3193. } /* END OF FUNCTION SaveWorkspaceResources */
  3194. /******************************<->*************************************
  3195. *
  3196. * AddStringToResourceData (string, pdata, plen)
  3197. *
  3198. * Description:
  3199. * -----------
  3200. * Adds a string to a growing buffer of strings.
  3201. *
  3202. * Inputs:
  3203. * ------
  3204. * string - string to add
  3205. * pdata - pointer to data pointer
  3206. * plen - number of bytes used in *pdata already
  3207. *
  3208. * Outputs:
  3209. * -------
  3210. * *pdata - data pointer (may be changed by XtRealloc)
  3211. * *plen - number of bytes used in *pdata (old value plus length
  3212. * of string
  3213. *
  3214. * Comments:
  3215. * ---------
  3216. *
  3217. *************************************<->***********************************/
  3218. void
  3219. AddStringToResourceData(
  3220. char *string,
  3221. char **pdata,
  3222. int *plen )
  3223. {
  3224. if ((*pdata = (char *) XtRealloc(*pdata, *plen+strlen(string)+1)) == NULL)
  3225. {
  3226. Warning (((char *)GETMESSAGE(76, 13, "Insufficient memory to save resources.")));
  3227. Do_Quit_Mwm (False);
  3228. }
  3229. strcat (*pdata, string);
  3230. *plen += strlen(string);
  3231. } /* END OF FUNCTION AddStringToResourceData */
  3232. /*************************************<->*************************************
  3233. *
  3234. * DuplicateWorkspaceName (pSD, name, num)
  3235. *
  3236. *
  3237. * Description:
  3238. * -----------
  3239. * This function searches the first "num" workspace names to see if the
  3240. * passed "name" duplicates any workspace name defined so far.
  3241. *
  3242. *
  3243. * Inputs:
  3244. * ------
  3245. * pSD = pointer to screen data
  3246. * name = potential string name for workspace
  3247. * num = number of workspaces to check against
  3248. *
  3249. * Outputs:
  3250. * -------
  3251. * Return = True if a dupicate was found
  3252. *
  3253. * Comments:
  3254. * --------
  3255. *
  3256. *************************************<->***********************************/
  3257. Boolean
  3258. DuplicateWorkspaceName (WmScreenData *pSD, unsigned char *name, int num)
  3259. {
  3260. int i;
  3261. Boolean duplicate = False;
  3262. if (pSD && pSD->pWS)
  3263. {
  3264. for (i = 0; (i < num) && !duplicate; i++)
  3265. {
  3266. if (!strcmp (pSD->pWS[i].name, (char *)name))
  3267. {
  3268. duplicate = True;
  3269. }
  3270. }
  3271. }
  3272. return (duplicate);
  3273. }
  3274. #ifdef DEBUG
  3275. int PrintWorkspaceList (pSD)
  3276. WmScreenData *pSD;
  3277. {
  3278. int i, j, k;
  3279. WmWorkspaceData *pWS;
  3280. ClientData *pCD;
  3281. ClientData *pClients[500];
  3282. int numSaved = 0;
  3283. Boolean Saved;
  3284. fprintf (stderr, "Screen: %d\n", pSD->screen);
  3285. for (i =0; i < pSD->numWorkspaces; i++)
  3286. {
  3287. pWS = &pSD->pWS[i];
  3288. fprintf (stderr, "\nWorkspace %s contains: \n", pWS->name);
  3289. for (j = 0; j < pWS->numClients; j++)
  3290. {
  3291. pCD = pWS->ppClients[j];
  3292. fprintf (stderr, "\t%s\n", pCD->clientName);
  3293. Saved = False;
  3294. for (k = 0; k < numSaved; k++)
  3295. {
  3296. if (pCD == pClients[k])
  3297. {
  3298. Saved = True;
  3299. break;
  3300. }
  3301. }
  3302. if (!Saved)
  3303. {
  3304. pClients[numSaved++] = pCD;
  3305. }
  3306. }
  3307. }
  3308. for (i = 0; i < numSaved; i++)
  3309. {
  3310. pCD = pClients[i];
  3311. fprintf (stderr, "\nClient %s is in: \n", pCD->clientName);
  3312. for (j = 0; j < pCD->numInhabited; j++)
  3313. {
  3314. pWS = GetWorkspaceData (pCD->pSD, pCD->pWsList[j].wsID);
  3315. fprintf (stderr, "\t%s\n", pWS->name);
  3316. }
  3317. }
  3318. } /* END OF FUNCTION PrintWorkspaceList */
  3319. #endif /* DEBUG */