WmWrkspace.c 81 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890
  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_BACKDROP_IMAGETYPE)
  2966. {
  2967. iLen = (strlen (res_class) + strlen (screenName) +
  2968. strlen (pWS->name) + strlen (WmNbackdrop) +
  2969. strlen (WmNimageType) + 22);
  2970. if (iLen > bufferLength)
  2971. {
  2972. bufferLength += iLen;
  2973. buffer = (char *)
  2974. XtRealloc (buffer, bufferLength * sizeof(char));
  2975. }
  2976. sprintf (buffer, "%s%s*%s*%s*%s: %d\n", res_class,
  2977. screenName, pWS->name,
  2978. WmNbackdrop, WmNimageType, pWS->backdrop.imageType);
  2979. AddStringToResourceData (buffer, &data, &cum_len);
  2980. }
  2981. if (flags & WM_RES_WORKSPACE_TITLE)
  2982. {
  2983. String asciiName;
  2984. asciiName = WmXmStringToString (pWS->title);
  2985. iLen = strlen (res_class) + strlen (screenName) +
  2986. strlen (pWS->name) + strlen (WmNtitle) +
  2987. strlen (asciiName) + 16;
  2988. if (iLen > bufferLength)
  2989. {
  2990. bufferLength += iLen;
  2991. buffer = (char *)
  2992. XtRealloc (buffer, bufferLength * sizeof(char));
  2993. }
  2994. sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
  2995. screenName, pWS->name,
  2996. WmNtitle, asciiName);
  2997. AddStringToResourceData (buffer, &data, &cum_len);
  2998. XtFree (asciiName);
  2999. }
  3000. if ((flags & WM_RES_INITIAL_WORKSPACE) &&
  3001. (!wmGD.useStandardBehavior))
  3002. {
  3003. iLen = strlen (res_class) + strlen (screenName) +
  3004. strlen (WmNinitialWorkspace) + strlen (pWS->name) + 14;
  3005. if (iLen > bufferLength)
  3006. {
  3007. bufferLength += iLen;
  3008. buffer = (char *)
  3009. XtRealloc (buffer, bufferLength * sizeof(char));
  3010. }
  3011. sprintf (buffer, "%s%s*%s: %s\n", res_class,
  3012. screenName,
  3013. WmNinitialWorkspace, pWS->name);
  3014. AddStringToResourceData (buffer, &data, &cum_len);
  3015. }
  3016. if ((flags & WM_RES_WORKSPACE_LIST) &&
  3017. (!wmGD.useStandardBehavior))
  3018. {
  3019. WmWorkspaceData *pWSi;
  3020. char *pchQname;
  3021. int i;
  3022. pWSi = pWS->pSD->pWS;
  3023. pchQname = (char *) _DtWmParseMakeQuotedString (
  3024. (unsigned char *)pWSi->name);
  3025. strcpy ((char *)wmGD.tmpBuffer, pchQname);
  3026. XtFree (pchQname);
  3027. pWSi++;
  3028. for (i=1; i<pWS->pSD->numWorkspaces; i++, pWSi++)
  3029. {
  3030. strcat ((char *)wmGD.tmpBuffer, " ");
  3031. pchQname = (char *) _DtWmParseMakeQuotedString (
  3032. (unsigned char *)pWSi->name);
  3033. strcat ((char *)wmGD.tmpBuffer, pchQname);
  3034. XtFree (pchQname);
  3035. }
  3036. sprintf (buffer, "%s%s*%s: %s\n", res_class,
  3037. screenName,
  3038. WmNworkspaceList, wmGD.tmpBuffer);
  3039. AddStringToResourceData (buffer, &data, &cum_len);
  3040. }
  3041. if ((flags & WM_RES_WORKSPACE_COUNT) &&
  3042. (!wmGD.useStandardBehavior))
  3043. {
  3044. char pchNumWs[20];
  3045. sprintf (pchNumWs, "%d", pWS->pSD->numWorkspaces);
  3046. iLen = strlen (res_class) + strlen (screenName) +
  3047. strlen (WmNworkspaceCount) + strlen (pchNumWs) + 14;
  3048. if (iLen > bufferLength)
  3049. {
  3050. bufferLength += iLen;
  3051. buffer = (char *)
  3052. XtRealloc (buffer, bufferLength * sizeof(char));
  3053. }
  3054. sprintf (buffer, "%s%s*%s: %s\n", res_class,
  3055. screenName,
  3056. WmNworkspaceCount, pchNumWs);
  3057. AddStringToResourceData (buffer, &data, &cum_len);
  3058. }
  3059. if ((flags & WM_RES_FP_POSITION) &&
  3060. (O_Shell(pPanelist)) &&
  3061. (!wmGD.useStandardBehavior) &&
  3062. (!XFindContext (DISPLAY, XtWindow(O_Shell(pPanelist)),
  3063. wmGD.windowContextType,
  3064. (XtPointer)&pCD_Panel)))
  3065. {
  3066. Position midX, midY, tmpX, tmpY;
  3067. Dimension screenWidth, screenHeight;
  3068. clientX = pCD_Panel->clientX;
  3069. clientY = pCD_Panel->clientY;
  3070. /*
  3071. * Determine quadrant that the front panel midpoint is
  3072. * in and save front panel with appropriate gravity.
  3073. */
  3074. /* find panel midpoint */
  3075. midX = clientX+(pCD_Panel->clientWidth >> 1);
  3076. midY = clientY+(pCD_Panel->clientHeight >> 1);
  3077. /* get screen dimensions */
  3078. screenWidth = XDisplayWidth (DISPLAY, pCD_Panel->pSD->screen);
  3079. screenHeight = XDisplayHeight (DISPLAY, pCD_Panel->pSD->screen);
  3080. /*
  3081. * Determine midpoint quadrant and set up client geometry
  3082. * relative to that corner. Adjust if positionIsFrame
  3083. * is being used.
  3084. */
  3085. if (midX <= (Position) screenWidth/2)
  3086. {
  3087. if(wmGD.positionIsFrame)
  3088. {
  3089. clientX -= pCD_Panel->frameInfo.upperBorderWidth;
  3090. }
  3091. /* West */
  3092. if (midY <= (Position) screenHeight/2)
  3093. {
  3094. /* NorthWest */
  3095. if(wmGD.positionIsFrame)
  3096. {
  3097. clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
  3098. pCD_Panel->frameInfo.titleBarHeight);
  3099. }
  3100. sprintf (tmpBuffer, "+%d+%d", clientX, clientY);
  3101. }
  3102. else
  3103. {
  3104. /* SouthWest */
  3105. clientY = screenHeight - clientY - pCD_Panel->clientHeight;
  3106. if(wmGD.positionIsFrame)
  3107. {
  3108. clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
  3109. }
  3110. sprintf (tmpBuffer, "+%d-%d", clientX, clientY);
  3111. }
  3112. }
  3113. else
  3114. {
  3115. clientX = screenWidth - clientX - pCD_Panel->clientWidth;
  3116. if (wmGD.positionIsFrame)
  3117. {
  3118. clientX -= pCD_Panel->frameInfo.lowerBorderWidth;
  3119. }
  3120. /* East */
  3121. if (midY <= (Position) screenHeight/2)
  3122. {
  3123. /* NorthEast */
  3124. if(wmGD.positionIsFrame)
  3125. {
  3126. clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
  3127. pCD_Panel->frameInfo.titleBarHeight);
  3128. }
  3129. sprintf (tmpBuffer, "-%d+%d", clientX, clientY);
  3130. }
  3131. else
  3132. {
  3133. /* SouthEast */
  3134. clientY = screenHeight - clientY - pCD_Panel->clientHeight;
  3135. if(wmGD.positionIsFrame)
  3136. {
  3137. clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
  3138. }
  3139. sprintf (tmpBuffer, "-%d-%d", clientX, clientY);
  3140. }
  3141. }
  3142. iLen = strlen (res_class) + strlen (screenName) +
  3143. strlen (XtName(O_Shell(pPanelist))) +
  3144. strlen (WmNgeometry) + strlen (tmpBuffer) + 18;
  3145. if (iLen > bufferLength)
  3146. {
  3147. bufferLength += iLen;
  3148. buffer = (char *)
  3149. XtRealloc (buffer, bufferLength * sizeof(char));
  3150. }
  3151. sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
  3152. screenName,
  3153. XtName (O_Shell(pPanelist)),
  3154. WmNgeometry, tmpBuffer);
  3155. AddStringToResourceData (buffer, &data, &cum_len);
  3156. }
  3157. if ((flags & WM_RES_ICONBOX_GEOMETRY) &&
  3158. (!wmGD.useStandardBehavior))
  3159. {
  3160. /* update iconbox geometry string */
  3161. if (pWS->iconBoxGeometry)
  3162. {
  3163. XtFree((char *) (pWS->iconBoxGeometry));
  3164. pWS->iconBoxGeometry = NULL;
  3165. }
  3166. clientWidth = (pWS->pIconBox->pCD_iconBox->clientWidth -
  3167. pWS->pIconBox->pCD_iconBox->baseWidth) /
  3168. pWS->pIconBox->pCD_iconBox->widthInc;
  3169. clientHeight = (pWS->pIconBox->pCD_iconBox->clientHeight -
  3170. pWS->pIconBox->pCD_iconBox->baseHeight) /
  3171. pWS->pIconBox->pCD_iconBox->heightInc ;
  3172. if(wmGD.positionIsFrame)
  3173. {
  3174. CalculateGravityOffset (pWS->pIconBox->pCD_iconBox, &xoff, &yoff);
  3175. clientX = pWS->pIconBox->pCD_iconBox->clientX - xoff;
  3176. clientY = pWS->pIconBox->pCD_iconBox->clientY - yoff;
  3177. }
  3178. else
  3179. {
  3180. clientX = pWS->pIconBox->pCD_iconBox->clientX;
  3181. clientY = pWS->pIconBox->pCD_iconBox->clientY;
  3182. }
  3183. sprintf (buffer, "%dx%d+%d+%d", clientWidth, clientHeight,
  3184. clientX, clientY);
  3185. pWS->iconBoxGeometry = strdup( buffer);
  3186. iLen = strlen (res_class) + strlen (screenName) +
  3187. strlen (pWS->name) + strlen (WmNiconBoxGeometry) +
  3188. strlen (pWS->iconBoxGeometry) + 18;
  3189. if (iLen > bufferLength)
  3190. {
  3191. bufferLength += iLen;
  3192. buffer = (char *)
  3193. XtRealloc (buffer, bufferLength * sizeof(char));
  3194. }
  3195. sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
  3196. screenName, pWS->name,
  3197. WmNiconBoxGeometry, pWS->iconBoxGeometry);
  3198. AddStringToResourceData (buffer, &data, &cum_len);
  3199. }
  3200. if (data)
  3201. {
  3202. /*
  3203. * Merge in the resource(s)
  3204. */
  3205. _DtAddToResource (DISPLAY, data);
  3206. XtFree(data);
  3207. }
  3208. XtFree(buffer);
  3209. } /* END OF FUNCTION SaveWorkspaceResources */
  3210. /******************************<->*************************************
  3211. *
  3212. * AddStringToResourceData (string, pdata, plen)
  3213. *
  3214. * Description:
  3215. * -----------
  3216. * Adds a string to a growing buffer of strings.
  3217. *
  3218. * Inputs:
  3219. * ------
  3220. * string - string to add
  3221. * pdata - pointer to data pointer
  3222. * plen - number of bytes used in *pdata already
  3223. *
  3224. * Outputs:
  3225. * -------
  3226. * *pdata - data pointer (may be changed by XtRealloc)
  3227. * *plen - number of bytes used in *pdata (old value plus length
  3228. * of string
  3229. *
  3230. * Comments:
  3231. * ---------
  3232. *
  3233. *************************************<->***********************************/
  3234. void
  3235. AddStringToResourceData(
  3236. char *string,
  3237. char **pdata,
  3238. int *plen )
  3239. {
  3240. if ((*pdata = (char *) XtRealloc(*pdata, *plen+strlen(string)+1)) == NULL)
  3241. {
  3242. Warning (((char *)GETMESSAGE(76, 13, "Insufficient memory to save resources.")));
  3243. Do_Quit_Mwm (False);
  3244. }
  3245. strcat (*pdata, string);
  3246. *plen += strlen(string);
  3247. } /* END OF FUNCTION AddStringToResourceData */
  3248. /*************************************<->*************************************
  3249. *
  3250. * DuplicateWorkspaceName (pSD, name, num)
  3251. *
  3252. *
  3253. * Description:
  3254. * -----------
  3255. * This function searches the first "num" workspace names to see if the
  3256. * passed "name" duplicates any workspace name defined so far.
  3257. *
  3258. *
  3259. * Inputs:
  3260. * ------
  3261. * pSD = pointer to screen data
  3262. * name = potential string name for workspace
  3263. * num = number of workspaces to check against
  3264. *
  3265. * Outputs:
  3266. * -------
  3267. * Return = True if a dupicate was found
  3268. *
  3269. * Comments:
  3270. * --------
  3271. *
  3272. *************************************<->***********************************/
  3273. Boolean
  3274. DuplicateWorkspaceName (WmScreenData *pSD, unsigned char *name, int num)
  3275. {
  3276. int i;
  3277. Boolean duplicate = False;
  3278. if (pSD && pSD->pWS)
  3279. {
  3280. for (i = 0; (i < num) && !duplicate; i++)
  3281. {
  3282. if (!strcmp (pSD->pWS[i].name, (char *)name))
  3283. {
  3284. duplicate = True;
  3285. }
  3286. }
  3287. }
  3288. return (duplicate);
  3289. }
  3290. #ifdef DEBUG
  3291. int PrintWorkspaceList (pSD)
  3292. WmScreenData *pSD;
  3293. {
  3294. int i, j, k;
  3295. WmWorkspaceData *pWS;
  3296. ClientData *pCD;
  3297. ClientData *pClients[500];
  3298. int numSaved = 0;
  3299. Boolean Saved;
  3300. fprintf (stderr, "Screen: %d\n", pSD->screen);
  3301. for (i =0; i < pSD->numWorkspaces; i++)
  3302. {
  3303. pWS = &pSD->pWS[i];
  3304. fprintf (stderr, "\nWorkspace %s contains: \n", pWS->name);
  3305. for (j = 0; j < pWS->numClients; j++)
  3306. {
  3307. pCD = pWS->ppClients[j];
  3308. fprintf (stderr, "\t%s\n", pCD->clientName);
  3309. Saved = False;
  3310. for (k = 0; k < numSaved; k++)
  3311. {
  3312. if (pCD == pClients[k])
  3313. {
  3314. Saved = True;
  3315. break;
  3316. }
  3317. }
  3318. if (!Saved)
  3319. {
  3320. pClients[numSaved++] = pCD;
  3321. }
  3322. }
  3323. }
  3324. for (i = 0; i < numSaved; i++)
  3325. {
  3326. pCD = pClients[i];
  3327. fprintf (stderr, "\nClient %s is in: \n", pCD->clientName);
  3328. for (j = 0; j < pCD->numInhabited; j++)
  3329. {
  3330. pWS = GetWorkspaceData (pCD->pSD, pCD->pWsList[j].wsID);
  3331. fprintf (stderr, "\t%s\n", pWS->name);
  3332. }
  3333. }
  3334. } /* END OF FUNCTION PrintWorkspaceList */
  3335. #endif /* DEBUG */