2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
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.
37 #include "WmResNames.h"
40 #include <X11/Xutil.h>
43 #include <Xm/AtomMgr.h>
48 #include "WmIPC.h" /* must be after DtP.h */
49 #include "WmPresence.h"
53 #define MIN(a,b) ((a)<=(b)?(a):(b))
57 #define MAX(a,b) ((a)>=(b)?(a):(b))
61 /* internally defined functions */
63 #include "WmWrkspace.h"
65 /******** Static Function Declarations ********/
67 static void InsureUniqueWorkspaceHints(
70 /******** End Static Function Declarations ********/
72 /* FindDtSessionMatch () put in WmResParse.h */
74 /* external functions */
75 #include "WmBackdrop.h"
77 #include "WmFunction.h"
79 #include "WmIconBox.h"
81 #include "WmProperty.h"
82 #include "WmResParse.h"
83 #include "WmWinInfo.h"
84 #include "WmWinList.h"
85 #include "WmWinState.h"
92 /* a dynamically allocated list of workspaces used
93 * by F_AddToAllWorkspaces
95 static int numResIDs = 0;
96 static WorkspaceID *pResIDs = NULL;
100 /*************************************<->*************************************
102 * ChangeToWorkspace (pNewWS)
107 * This function changes to a new workspace.
111 * pNewWS = pointer to workspace data
114 *************************************<->***********************************/
118 WmWorkspaceData *pNewWS )
123 WmScreenData *pSD = pNewWS->pSD;
126 Context wsContext = F_CONTEXT_NONE;
128 if (pNewWS == pSD->pActiveWS)
129 return; /* already there */
131 pSD->pLastWS = pSD->pActiveWS;
134 * Go through client list of old workspace and hide windows
135 * that shouldn't appear in new workspace.
138 if (pSD->presence.shellW &&
139 pSD->presence.onScreen &&
140 pSD->presence.contextForClient == F_CONTEXT_ICON)
142 pWsPCD = pSD->presence.pCDforClient;
143 wsContext = pSD->presence.contextForClient;
144 HidePresenceBox (pSD, False);
147 for (i = 0; i < pSD->pActiveWS->numClients; i++)
149 pCD = pSD->pActiveWS->ppClients[i];
150 if (!ClientInWorkspace (pNewWS, pCD))
152 SetClientWsIndex(pCD);
153 SetClientState (pCD, pCD->clientState | UNSEEN_STATE,
159 * Hide active icon text label
161 if ((pSD->iconDecoration & ICON_ACTIVE_LABEL_PART) &&
162 wmGD.activeIconTextDisplayed)
164 HideActiveIconText(pSD);
172 UnmapIconBoxes (pSD->pLastWS);
176 * Set new active workspace
178 pSD->pActiveWS = pNewWS;
179 ChangeBackdrop (pNewWS);
182 * Go through client list of new workspace and show windows
183 * that should appear.
185 for (i = 0; i < pNewWS->numClients; i++)
187 pCD = pNewWS->ppClients[i];
188 SetClientWsIndex(pCD);
189 if (pCD->clientState & UNSEEN_STATE)
192 (pCD->clientState & ~UNSEEN_STATE), CurrentTime);
194 if ((pCD->clientState == MINIMIZED_STATE) &&
195 ((!pCD->pSD->useIconBox) ||
198 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
199 ICON_X(pCD), ICON_Y(pCD));
204 unsigned int xOffset, yOffset;
207 * Adjust for icons in the box
210 if (pNewWS->pIconBox)
212 xOffset = IB_MARGIN_WIDTH;
213 yOffset = IB_MARGIN_HEIGHT;
222 * reparent icon window to frame in this workspace
224 if ((ICON_DECORATION(pCD) & ICON_IMAGE_PART) &&
227 ReparentIconWindow (pCD, xOffset, yOffset);
232 if ( (wsContext == F_CONTEXT_ICON &&
233 ClientInWorkspace (ACTIVE_WS, pWsPCD)) ||
235 (pSD->presence.shellW &&
236 ! pSD->presence.userDismissed &&
237 ClientInWorkspace (ACTIVE_WS, pSD->presence.pCDforClient) &&
238 pSD->presence.contextForClient == F_CONTEXT_ICON))
240 ShowPresenceBox(pSD->presence.pCDforClient, F_CONTEXT_ICON);
244 /* sync up workspace info property with current state */
245 UpdateWorkspaceInfoProperty (pSD);
247 SetCurrentWorkspaceProperty (pSD);
249 /* send workspace change broadcast message */
250 dtSendWorkspaceModifyNotification(pSD, (Atom) pNewWS->id,
251 DtWSM_REASON_CURRENT);
253 } /* END OF FUNCTION ChangeToWorkspace */
255 /******************************<->*************************************
257 * ChangeWorkspaceTitle (pWS, pchTitle)
261 * Set the title for a workspace.
265 * pWS = pointer to workspace data
266 * pchTitle = new title to assign to this workspace
275 ******************************<->***********************************/
278 ChangeWorkspaceTitle(
279 WmWorkspaceData *pWS,
285 * Convert string to XmString
287 xmstr = XmStringCreateLocalized (pchTitle);
294 * Replace title in workspace data
296 XmStringFree (pWS->title);
300 * Save changes to resource database
302 SaveWorkspaceResources (pWS, (WM_RES_WORKSPACE_TITLE));
305 * Replace old workspace in info property
307 SetWorkspaceInfoProperty (pWS);
309 UpdateWorkspaceInfoProperty (pWS->pSD);
314 * Inform the world of the new workspace title
316 dtSendWorkspaceModifyNotification(pWS->pSD, pWS->id, DtWSM_REASON_TITLE);
318 } /* END OF FUNCTION ChangeWorkspaceTitle */
321 /*************************************<->*************************************
323 * UpdateWorkspacePresenceProperty (pCD)
328 * This function updates the _DT_WORKSPACE_PRESENCE property for a
333 * pCD = pointer to client data
336 *************************************<->***********************************/
339 UpdateWorkspacePresenceProperty(
343 static Atom *pPresence = NULL;
344 static unsigned long cPresence = 0;
347 if (wmGD.useStandardBehavior)
350 * Don't change any workspace properties in standard behavior
358 /* allocate initial list */
359 if (!(pPresence = (Atom *)
360 XtMalloc (pCD->pSD->numWorkspaces * sizeof(Atom))))
362 Warning (((char *)GETMESSAGE(76, 1, "Insufficient memory for workspace presence property")));
366 cPresence = pCD->pSD->numWorkspaces;
370 if (cPresence < pCD->numInhabited)
372 /* allocate bigger list */
373 if (!(pPresence = (Atom *)
374 XtRealloc ((char *)pPresence, pCD->numInhabited * sizeof(Atom))))
376 Warning (((char *)GETMESSAGE(76, 2, "Insufficient memory for workspace presence property")));
380 cPresence = pCD->numInhabited;
384 for (i = 0; (i < pCD->numInhabited) && (i < cPresence) ; i++)
386 pPresence[i] = pCD->pWsList[i].wsID;
389 SetWorkspacePresence (pCD->client, pPresence,
390 MIN(pCD->numInhabited, cPresence));
392 } /* END OF FUNCTION UpdateWorkspacePresenceProperty */
396 /*************************************<->*************************************
398 * UpdateWorkspaceInfoProperty (pSD)
403 * This function updates the _DT_WORKSPACE_INFO property for the
408 * pSD = pointer to screen data
411 *************************************<->***********************************/
414 UpdateWorkspaceInfoProperty(
418 WorkspaceInfo *pWsInfo;
419 WmWorkspaceData *pws;
422 if (wmGD.useStandardBehavior)
425 * Don't change any workspace properties in standard behavior
431 if (pWsInfo = (WorkspaceInfo *)
432 XtMalloc (pSD->numWorkspaces * sizeof(WorkspaceInfo)))
434 /* put current workspace at top of list */
435 pWsInfo[0].workspace = pSD->pActiveWS->id;
436 pWsInfo[0].backgroundWindow = pSD->pActiveWS->backdrop.window;
437 pWsInfo[0].bg = pSD->pActiveWS->backdrop.background;
438 pWsInfo[0].fg = pSD->pActiveWS->backdrop.foreground;
439 pWsInfo[0].backdropName = pSD->pActiveWS->backdrop.nameAtom;
441 /* add in the rest of the workspaces */
443 for (count = 1; count < pSD->numWorkspaces; count++)
445 if (pWsInfo[0].workspace == pws->id)
446 pws++; /* already at top, skip this one */
448 pWsInfo[count].workspace = pws->id;
449 pWsInfo[count].backgroundWindow = pws->backdrop.window;
450 pWsInfo[count].bg = pws->backdrop.background;
451 pWsInfo[count].fg = pws->backdrop.foreground;
452 pWsInfo[count].backdropName = pws->backdrop.nameAtom;
456 /* set the property */
457 SetWorkspaceInfo (pSD->wmWorkspaceWin, pWsInfo,
460 XtFree ((char *)pWsInfo);
464 Warning (((char *)GETMESSAGE(76, 3, "Insufficient memory to update workspace info")));
467 } /* END OF FUNCTION UpdateWorkspaceInfoProperty */
471 /*************************************<->*************************************
473 * AddPersistentWindow (pWS)
478 * This function adds windows that want to be in all workspaces to
479 * the workspace passed in.
483 * pWS = pointer to workspace data
488 *************************************<->***********************************/
491 AddPersistentWindows(
492 WmWorkspaceData *pWS)
495 WmScreenData *pSD = pWS->pSD;
497 ClientListEntry *pCLE;
500 * For all the windows managed for this screen, see if they
501 * want to be in all workspaces and add them to this workspace.
503 pCLE = pSD->clientList;
508 * Process all the non-icon client list entries
510 if ((pCLE->type == NORMAL_STATE) &&
511 (pCLE->pCD->putInAll))
513 AddClientToWorkspaces( pCLE->pCD, &(pWS->id), 1 );
517 * Test for exit condition and advance client list pointer
519 if (pCLE == pSD->lastClient)
522 pCLE = pCLE->nextSibling;
525 } /* END OF FUNCTION AddPersistentWindows */
528 /*************************************<->*************************************
530 * CreateWorkspace (pSD, pchTitle)
535 * This function creates a new workspace.
539 * pSD = pointer to screen data
540 * pchTitle = user-visible title for the workspace (may be NULL)
544 * Returns pointer to workspace data if successful.
546 *************************************<->***********************************/
551 unsigned char *pchTitle )
554 WmWorkspaceData *pWS = NULL;
559 * Allocate more workspace datas if we have no spares
561 if (pSD->numWsDataAllocated <= pSD->numWorkspaces)
563 iActiveWS = (pSD->pActiveWS - pSD->pWS) / sizeof (WmWorkspaceData);
564 pSD->numWsDataAllocated += WS_ALLOC_AMOUNT;
565 pSD->pWS = (WmWorkspaceData *) XtRealloc ((char *)pSD->pWS,
566 pSD->numWsDataAllocated * sizeof(WmWorkspaceData));
567 pSD->pActiveWS = &(pSD->pWS[iActiveWS]);
571 * Give this workspace a name
573 pWS = &pSD->pWS[pSD->numWorkspaces];
574 string = (String) GenerateWorkspaceName (pSD, pSD->numWorkspaces);
575 pWS->name = XtNewString (string);
578 * Initialize the workspace data structure
580 InitWmWorkspace (pWS, pSD);
584 XmStringFree (pWS->title);
585 pWS->title = XmStringCreateLocalized ((char *)pchTitle);
589 * bump workspace count
591 pSD->numWorkspaces++;
594 * update the properties that announce workspace info
596 SetWorkspaceInfoProperty (pWS);
597 SetWorkspaceListProperty (pSD);
599 SaveWorkspaceResources(pWS, (WM_RES_WORKSPACE_LIST |
600 WM_RES_WORKSPACE_COUNT |
601 WM_RES_WORKSPACE_TITLE));
602 dtSendWorkspaceModifyNotification(pSD, pWS->id, DtWSM_REASON_ADD);
605 * Insure there's an iconbox for this workspace
609 AddIconBoxForWorkspace (pWS);
613 * Add windows to this workspaces that want to be in "all"
616 AddPersistentWindows (pWS);
619 * Update workspace presence dialog data
621 UpdatePresenceWorkspaces(pSD);
624 } /* END OF FUNCTION CreateWorkspace */
627 /*************************************<->*************************************
629 * DeleteWorkspace (pWS)
634 * This function deletes a workspace.
638 * pWS = pointer to screen data
642 * Returns pointer to workspace data if successful.
644 *************************************<->***********************************/
648 WmWorkspaceData *pWS )
651 WmWorkspaceData *pWSdest; /* destination WS */
654 WmScreenData *pSD = pWS->pSD;
657 if (pSD->numWorkspaces > 1)
660 * Find index for "next" workspace
662 for (iNextWs = 0; iNextWs < pSD->numWorkspaces; iNextWs++)
664 if (pSD->pWS[iNextWs].id == pWS->id)
671 /* check bounds and wrap */
672 if (iNextWs >= pSD->numWorkspaces)
676 * Determine default destination for clients that exist
677 * only in the workspace being deleted.
679 if (pWS == ACTIVE_WS)
681 pWSdest = &(pSD->pWS[iNextWs]);
686 * Use the "current" workspace as the default destination
692 * Move all clients out of this workspace
694 while (pWS->numClients > 0)
696 /* repeatedly remove the first one until all are gone */
697 pCD = pWS->ppClients[0];
700 if (pCD->numInhabited == 1)
702 if (!(pCD->clientFlags & (ICON_BOX)))
704 AddClientToWorkspaces (pCD, &(pWSdest->id), 1);
708 RemoveClientFromWorkspaces (pCD, &(pWS->id), 1);
712 * If we're deleting the current workspace,
713 * then change to another workspace.
715 if (pWS == ACTIVE_WS)
717 ChangeToWorkspace (pWSdest);
721 * Save the workspace ID for the notification message.
726 * Destroy the icon box for the workspace if one was used
730 DestroyIconBox (pWS);
734 * Delete the property containing information on this workspace
736 DeleteWorkspaceInfoProperty (pWS);
739 * Delete the workspace data structures
741 if (pWS->backdrop.imagePixmap)
743 if (!XmDestroyPixmap (XtScreen(pWS->workspaceTopLevelW),
744 pWS->backdrop.imagePixmap))
746 /* not in Xm pixmap cache */
750 /* free pWS->backdrop.image */
751 if ((pWS->backdrop.flags & BACKDROP_IMAGE_ALLOCED) &&
752 (pWS->backdrop.image))
754 free (pWS->backdrop.image);
758 * Free up icon placement data
760 if (wmGD.iconAutoPlace)
762 if (pWS->IPData.placeList != NULL)
763 XtFree ((char *) pWS->IPData.placeList);
764 if (pWS->IPData.placementRowY != NULL)
765 XtFree ((char *) pWS->IPData.placementRowY);
766 if (pWS->IPData.placementColX != NULL)
767 XtFree ((char *) pWS->IPData.placementColX);
770 XtFree ((char *) pWS->name);
771 XmStringFree (pWS->title);
772 XtFree ((char *) pWS->ppClients);
773 if (pWS->iconBoxGeometry) XtFree ((char *) pWS->iconBoxGeometry);
774 XtDestroyWidget (pWS->workspaceTopLevelW);
777 * Compress the list of workspaces if we're not deleting
778 * the last one. (Do piece-wise to avoid overlapping copy
783 WmWorkspaceData *pWSdest;
784 WmWorkspaceData *pWSsrc;
788 pWSsrc = &(pSD->pWS[iNextWs]);
790 for (j=iNextWs; j < pSD->numWorkspaces; j++)
792 memcpy (pWSdest, pWSsrc, sizeof(WmWorkspaceData));
793 if (pSD->pActiveWS == pWSsrc)
795 pSD->pActiveWS = pWSdest;
803 * We now have one less workspace.
805 pSD->numWorkspaces--;
808 * Update the properties that announce workspace info.
810 SetWorkspaceListProperty (pSD);
812 SaveWorkspaceResources(pWSdest,
813 (WM_RES_WORKSPACE_LIST | WM_RES_WORKSPACE_COUNT));
815 dtSendWorkspaceModifyNotification(pSD, aOldId, DtWSM_REASON_DELETE);
818 * Update workspace presence dialog data
820 UpdatePresenceWorkspaces(pSD);
822 } /* END OF FUNCTION DeleteWorkspace */
825 /*************************************<->*************************************
827 * ProcessDtWmHints (pCD)
832 * Process the _DT_WM_HINTS property on the window (if any).
837 * pCD = pointer to client data
842 * pCD = may be changed.
844 *************************************<->***********************************/
847 ProcessDtWmHints (ClientData *pCD)
857 * Retrieve the _DT_WM_HINTS property if it exists.
860 property = XmInternAtom(DISPLAY, _XA_DT_WM_HINTS, False);
862 propertyVUE = XmInternAtom(DISPLAY, _XA_VUE_WM_HINTS, False);
867 ((HasProperty (pCD, property)) || (HasProperty (pCD, propertyVUE)))
869 (HasProperty (pCD, property))
871 && (_DtWsmGetDtWmHints (DISPLAY, pCD->client, &pHints) == Success))
873 pCD->clientFlags |= GOT_DT_WM_HINTS;
874 if (pHints->flags & DtWM_HINTS_FUNCTIONS)
876 if (pHints->functions & DtWM_FUNCTION_ALL)
878 /* client indicating inapplicable functions */
879 pCD->dtwmFunctions &= ~(pHints->functions);
883 /* client indicating applicable functions */
884 pCD->dtwmFunctions &= pHints->functions;
888 if (pHints->flags & DtWM_HINTS_BEHAVIORS)
890 /* set applicable behaviors */
891 pCD->dtwmBehaviors = pHints->behaviors;
892 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
895 * if this is a restored subpanel, remove the
896 * DtWM_BEHAVIOR_SUB_RESTORED bit so the next
897 * time through the subpanel will behave as an
900 pHints->behaviors &= ~DtWM_BEHAVIOR_SUB_RESTORED;
901 _DtWsmSetDtWmHints (DISPLAY, pCD->client, pHints);
905 XFree ((char*)pHints);
908 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_PANEL)
910 /* put it in all workspaces */
911 saveFunctions = pCD->dtwmFunctions;
912 pCD->dtwmFunctions |= DtWM_FUNCTION_OCCUPY_WS;
914 F_AddToAllWorkspaces (NULL, pCD, NULL);
916 pCD->dtwmFunctions = saveFunctions;
917 pCD->clientFlags |= FRONT_PANEL_BOX ;
919 } /* END OF ProcessDtWmHints */
922 /*************************************<->*************************************
924 * GetClientWorkspaceInfo (pCD, manageFlags);
929 * This function sets up the portion of client data that has to
934 * pCD = pointer to client data (only partly initialized!!)
935 * manageFlags = tells us, in particular, if we're restarting.
939 * pCD = updated client data
941 *************************************<->***********************************/
944 GetClientWorkspaceInfo(
951 unsigned int numIDs = 0;
955 * Allocate initial workspace ID list
958 if ((pCD->pWsList = (WsClientData *)
959 XtMalloc(pCD->pSD->numWorkspaces * sizeof(WsClientData))) == NULL)
961 Warning (((char *)GETMESSAGE(76, 4, "Insufficient memory for client data")));
965 pCD->pWorkspaceHints = NULL;
966 pCD->sizeWsList = pCD->pSD->numWorkspaces;
967 pCD->numInhabited = 0; /* no valid ones yet */
968 for (i = 0; i < pCD->pSD->numWorkspaces; i++)
970 pCD->pWsList[i].wsID = None;
971 pCD->pWsList[i].iconPlace = NO_ICON_PLACE;
972 pCD->pWsList[i].iconX = 0;
973 pCD->pWsList[i].iconY = 0;
974 pCD->pWsList[i].iconFrameWin = None;
975 pCD->pWsList[i].pIconBox = NULL;
977 pCD->putInAll = bAll = False;
980 * Determine initial workspace set.
982 * If this is a secondary window, use the hints from the
983 * transient tree leader.
985 * Else if we're restarting, then use our own workspace presence.
987 * Else if a command line option is specified, use that.
989 * Else, if workspace hints are on the window, then use them.
991 * If none of the above work out, the window will be put into
992 * the current workspace.
995 ((pCD->transientLeader && GetLeaderPresence(pCD, &pIDs, &numIDs)) ||
996 ((manageFlags & MANAGEW_WM_RESTART) &&
997 GetMyOwnPresence (pCD, &pIDs, &numIDs)) ||
998 (WorkspaceIsInCommand (DISPLAY, pCD, &pIDs, &numIDs)) ||
1001 (HasProperty (pCD, wmGD.xa_DT_WORKSPACE_HINTS) ||
1003 XmInternAtom (DISPLAY, _XA_VUE_WORKSPACE_HINTS,
1006 HasProperty (pCD, wmGD.xa_DT_WORKSPACE_HINTS)
1008 && (GetWorkspaceHints (DISPLAY, pCD->client, &pIDs, &numIDs, &bAll) ==
1013 * Got some workspace hints!
1015 pCD->putInAll = bAll;
1016 ProcessWorkspaceHintList (pCD, pIDs, numIDs);
1019 if (pCD->numInhabited == 0)
1022 * If not in any workspaces, then put the client into
1025 PutClientIntoWorkspace (pCD->pSD->pActiveWS, pCD);
1030 } /* END OF FUNCTION GetClientWorkspaceInfo */
1033 /*************************************<->*************************************
1035 * WorkspaceIsInCommand (dpy, pCD, ppIDs, pNumIDs)
1040 * Determine if workspace specification is in command line for client
1045 * dpy - pointer to display structure
1046 * pCD - ptr to client data
1047 * ppIDs - pointer for returning list of IDs
1048 * pNumIDs - number of IDs being returned
1052 * ppIDs - returned list of IDs
1053 * pNumIDs - number of IDs being returned
1055 * Return - True if workspace option found, false otherwise
1060 * Malloc's memory that must be freed
1062 *************************************<->***********************************/
1065 WorkspaceIsInCommand(
1068 WorkspaceID **ppIDs,
1069 unsigned int *pNumIDs )
1072 char **wmcArgv = NULL;
1073 Boolean rval = False;
1074 unsigned char *pch = NULL;
1075 XTextProperty clientMachineProp;
1077 if (FindClientDBMatch(pCD, (char **)&pch))
1081 if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
1085 XtFree((char *)pch);
1088 else if (HasProperty (pCD, XA_WM_COMMAND) &&
1089 XGetCommand (dpy, pCD->client, &wmcArgv, &wmcArgc) &&
1092 if (pCD->pSD->remainingSessionItems)
1094 if(!(XGetWMClientMachine(dpy, pCD->client, &clientMachineProp)))
1096 clientMachineProp.value = NULL;
1098 if (FindDtSessionMatch(wmcArgc, wmcArgv, pCD, pCD->pSD,
1100 (char *)clientMachineProp.value))
1103 * If we found a match to a client description
1104 * in the DtSessionHints, use the information from
1105 * the Hints instead of the command line
1109 if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
1114 * free malloced memory containing workspace list
1116 XtFree ((char *)pch);
1120 if (clientMachineProp.value)
1122 XFree ((char*)clientMachineProp.value);
1126 if (!rval && FindWsNameInCommand (wmcArgc, wmcArgv, &pch))
1128 if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
1134 if (wmcArgv != NULL)
1136 XFreeStringList (wmcArgv);
1141 } /* END OF FUNCTION WorkspaceIsInCommand */
1144 /*************************************<->*************************************
1146 * ConvertNamesToIDs (pSD, pch, ppAtoms, pNumAtoms)
1151 * Takes a string containing a list of names separated by white space
1152 * and converts it to a list of workspace IDs.
1156 * pSD - pointer to screen data
1157 * pchIn - pointer to original string
1158 * ppAtoms - pointer to an atom pointer (for returning list pointer)
1159 * pNumAtoms - pointer to the number of atoms being returned.
1163 * *ppAtoms - points to a list of atoms returned.
1164 * *pNumAtoms - the number of atoms being returned.
1166 * Return - True if some Atoms are being returned
1170 * Processes local copy of string so that pch is not modified.
1172 * The list of atoms returned has been dynamically allocated.
1173 * Please XtFree() it when you're done.
1175 *************************************<->***********************************/
1180 unsigned char *pchIn,
1181 WorkspaceID **ppAtoms,
1182 unsigned int *pNumAtoms )
1185 unsigned char *pchLocal, *pch, *pchName;
1188 WorkspaceID *pLocalIDs;
1190 if ((pLocalIDs = (WorkspaceID *) XtMalloc (WS_ALLOC_AMOUNT *
1191 sizeof(WorkspaceID))) == NULL)
1193 Warning (((char *)GETMESSAGE(76, 5, "Insufficient Memory (ConvertNamesToIDs)")));
1194 ExitWM (WM_ERROR_EXIT_VALUE);
1196 numLocalIDs = WS_ALLOC_AMOUNT;
1198 if (pchIn && (pchLocal = (unsigned char *) XtMalloc(1+strlen((char *)pchIn))))
1200 strcpy ((char *)pchLocal, (char *)pchIn);
1203 while ((pchName = GetSmartString (&pch)))
1209 * Check workspace for workspace titles; map to
1212 xms = XmStringCreateLocalized ((char *)pchName);
1213 for (iwsx = 0; iwsx < pSD->numWorkspaces; iwsx++)
1215 if (XmStringCompare (xms, pSD->pWS[iwsx].title))
1222 if (iwsx < pSD->numWorkspaces)
1225 * Found a workspace title we've got,
1226 * use id for workspace name
1228 pLocalIDs[num] = pSD->pWS[iwsx].id;
1234 * Try for match on workspace name
1236 pLocalIDs[num] = (WorkspaceID)
1237 XInternAtom (DISPLAY, (char *)pchName, False);
1241 if (num >= numLocalIDs)
1243 /* list too small */
1244 numLocalIDs += WS_ALLOC_AMOUNT;
1245 if ((pLocalIDs = (WorkspaceID *) XtRealloc ((char *)pLocalIDs,
1246 numLocalIDs * sizeof(WorkspaceID))) == NULL)
1248 Warning (((char *)GETMESSAGE(76, 6, "Insufficient Memory (ConvertNamesToIDs)")));
1249 ExitWM (WM_ERROR_EXIT_VALUE);
1254 XtFree ((char *)pchLocal);
1257 *ppAtoms = pLocalIDs;
1261 } /* END OF FUNCTION ConvertNamesToIDs */
1264 /*************************************<->*************************************
1266 * CheckForPutInAllRequest (pCD, pIDs, numIDs)
1271 * Tests for the presence of the "all" atom in the atom list
1272 * and sets the "putInAll" flag on the client.
1276 * pCD - pointer to client data
1277 * pIDs - pointer to ID list
1278 * numIDs - number of IDs in list
1282 * pCD - putInAll member may be set
1284 *************************************<->***********************************/
1287 CheckForPutInAllRequest(
1290 unsigned int numIDs )
1295 for (i = 0; (i < numIDs) && !(pCD->putInAll); i++)
1297 if (pIDs[i] == wmGD.xa_ALL_WORKSPACES)
1299 pCD->putInAll = True;
1304 } /* END OF FUNCTION CheckForPutInAllRequest */
1307 /*************************************<->*************************************
1309 * FindWsNameInCommand (argc, argv, ppch)
1314 * Finds and returns the workspace name option in the command line
1319 * argc - argument count
1320 * argv - argument list
1321 * ppch - string pointer to return
1326 * *ppch - points to ws name (if found)
1328 * Return - True if wsname found
1333 *************************************<->***********************************/
1336 FindWsNameInCommand(
1339 unsigned char **ppch )
1343 #define XRM_OPT "-xrm"
1344 #define WSLIST "*workspaceList:"
1345 #define WSLIST_LEN 14
1348 Boolean rval = False;
1349 unsigned char *pch, *pchTmp, *pch0;
1350 unsigned char *pchRes, *pchValue;
1354 while (--argc && !rval)
1356 if (!strcmp(argv[i], XRM_OPT) && (argc > 1))
1359 * found "-xrm", now look at resource spec
1361 pch0 = (unsigned char *) strdup (argv[i+1]);
1364 Warning (((char *)GETMESSAGE(76, 7, "Insufficient memory")));
1365 ExitWM (WM_ERROR_EXIT_VALUE);
1369 /* strip off quotes ,
1370 * separate two halve of resource spec
1372 pchRes = GetSmartString (&pch);
1375 if ((*pchRes) && (*pch))
1377 /* Erase colon at end of resource name */
1379 pch = (unsigned char *) strrchr((char *)pchRes, ':');
1385 /* find beginning of last component of resource
1388 pch = (unsigned char *) strrchr ((char *)pchRes, '*');
1389 pchTmp = (unsigned char *) strrchr ((char *)pchRes, '.');
1395 if (pch && *pch && *(pch+1))
1400 /* compare resource with our resource */
1402 if ( (!strcmp ((char *)pch, WmNworkspaceList)) ||
1403 (!strcmp ((char *)pch, WmCWorkspaceList)))
1405 /* match, compute return position in
1408 *ppch = (unsigned char *)
1409 (argv[i+1] + (pchValue - pch0));
1411 XtFree ((char *)pch0);
1416 i++; /* skip next arg */
1421 XtFree ((char *)pch0);
1428 } /* END OF FUNCTION FindWsNameInCommand */
1432 /*************************************<->*************************************
1434 * PutClientIntoWorkspace (pWS, pCD)
1439 * This function updates the data for the client and workspace to
1440 * reflect the presence of the client in the workspace.
1444 * pWS = pointer to workspace data
1445 * pCD = pointer to client data
1450 *************************************<->***********************************/
1453 PutClientIntoWorkspace(
1454 WmWorkspaceData *pWS,
1458 int i = pCD->numInhabited;
1461 /* insure the client's got enough workspace data */
1462 if (pCD->sizeWsList < pCD->pSD->numWorkspaces)
1464 iAdded = pCD->pSD->numWorkspaces - pCD->sizeWsList;
1466 pCD->sizeWsList = pCD->pSD->numWorkspaces;
1467 pCD->pWsList = (WsClientData *)
1468 XtRealloc((char *)pCD->pWsList,
1469 (pCD->pSD->numWorkspaces * sizeof(WsClientData)));
1471 /* intialized new data */
1472 j = pCD->sizeWsList - 1;
1473 for (j=1; j <= iAdded; j++)
1475 k = pCD->sizeWsList - j;
1476 pCD->pWsList[k].iconPlace = NO_ICON_PLACE;
1477 pCD->pWsList[k].iconX = 0;
1478 pCD->pWsList[k].iconY = 0;
1479 pCD->pWsList[k].iconFrameWin = (Window) 0;
1480 pCD->pWsList[k].pIconBox = NULL;
1485 /* update the client's list of workspace data */
1486 pCD->pWsList[i].wsID = pWS->id;
1487 pCD->numInhabited++;
1489 if (!(pCD->clientFlags & WM_INITIALIZATION))
1492 * Make sure there's an icon
1493 * (Don't do this during initialization, the pCD not
1494 * ready for icon making yet).
1496 InsureIconForWorkspace (pWS, pCD);
1499 /* update the workspace list of clients */
1500 AddClientToWsList (pWS, pCD);
1502 } /* END OF FUNCTION PutClientIntoWorkspace */
1505 /*************************************<->*************************************
1507 * TakeClientOutOfWorkspace (pWS, pCD)
1512 * This function updates the data for the client and the workspace
1513 * to reflect the removal of the client from the workspace.
1517 * pWS = pointer to workspace data
1518 * pCD = pointer to client data
1523 *************************************<->***********************************/
1526 TakeClientOutOfWorkspace(
1527 WmWorkspaceData *pWS,
1532 Boolean Copying = False;
1535 if (pWS && pCD && ClientInWorkspace(pWS, pCD))
1540 if (!pCD->transientLeader)
1542 pWsc = GetWsClientData (pWS, pCD);
1544 if ((pCD->pSD->useIconBox) &&
1546 (pCD->clientFunctions & MWM_FUNC_MINIMIZE))
1548 DeleteIconFromBox (pWS->pIconBox, pCD);
1550 else if (wmGD.iconAutoPlace)
1553 * Free up root icon spot
1556 if ((pWsc->iconPlace != NO_ICON_PLACE) &&
1557 (pWS->IPData.placeList[pWsc->iconPlace].pCD == pCD))
1559 pWS->IPData.placeList[pWsc->iconPlace].pCD = NULL;
1560 pWsc->iconPlace = NO_ICON_PLACE;
1566 * Remove the selected workspace and copy the remaining ones
1567 * up. (Do piece-wise to avoid overlapping copy.)
1569 for (ixA = 0; ixA < pCD->numInhabited; ixA++)
1573 memcpy (&pCD->pWsList[ixA-1], &pCD->pWsList[ixA],
1574 sizeof(WsClientData));
1576 else if (pCD->pWsList[ixA].wsID == pWS->id)
1579 * This is the one we're removing, start copying here.
1586 * Decrement the number of workspaces inhabited.
1588 pCD->numInhabited--;
1590 /* update the workspaces list of clients */
1591 RemoveClientFromWsList (pWS, pCD);
1596 Warning("TakeClientOutOfWorkspace: null workspace passed in.");
1601 } /* END OF FUNCTION TakeClientOutOfWorkspace */
1604 /*************************************<->*************************************
1606 * GetWorkspaceData (pSD, wsID)
1611 * This function finds the data that is associated with a workspace ID.
1615 * pSD = pointer to screen data
1616 * wsID = workspace ID
1620 * Function returns a pointer to the workspace data if successful,
1621 * or NULL if unsuccessful.
1623 *************************************<->***********************************/
1631 WmWorkspaceData *pWS = NULL;
1634 for (i=0; i < pSD->numWorkspaces; i++)
1636 if (pSD->pWS[i].id == wsID)
1646 /* failed to find one */
1647 Warning ("Failed to find workspace data");
1653 } /* END OF FUNCTION GetWorkspaceData */
1657 /*************************************<->*************************************
1659 * GenerateWorkspaceName (pSD, wsnum)
1664 * This function generates and returns a workspace string name from
1665 * a small number passed in.
1669 * pSD = pointer to screen data
1670 * wsNum = number for workspace
1675 * returns pointer to statically allocated data. You must copy it
1676 * to your local buffer.
1680 * Name is of the form ws<n> where <n> is a number.
1682 *************************************<->***********************************/
1685 GenerateWorkspaceName(
1690 static unsigned char nameReturned[13];
1694 * Nice n-squared algorithm...
1695 * (This should be OK for small number of workspaces)
1697 for (i=0; i <= pSD->numWorkspaces; i++)
1699 /* generate a name */
1700 sprintf ((char *)nameReturned, "ws%d", i);
1701 if (!DuplicateWorkspaceName (pSD, nameReturned, wsnum))
1705 return (nameReturned);
1707 } /* END OF FUNCTION GenerateWorkspaceName */
1711 /*************************************<->*************************************
1713 * InWindowList (w, wl, num)
1718 * This function determines if a window is in a list of windows
1722 * w = window of interest
1723 * wl = list of windows
1724 * num = number of windows in wl
1729 * The function returns "True" if "w" appears in "wl"
1731 *************************************<->***********************************/
1741 Boolean rval = False;
1743 for (i = 0; (i < num) && !rval; i++)
1753 } /* END OF FUNCTION InWindowList */
1756 /*************************************<->*************************************
1758 * ClientInWorkspace (pWS, pCD)
1763 * This function determines if a client is in a workspace
1767 * pWS = pointer to workspace data
1768 * pCD = pointer to client data
1772 * The function returns "True" if client pCD is in workspace pWS
1774 *************************************<->***********************************/
1778 WmWorkspaceData *pWS,
1783 Boolean rval = False;
1785 for (i = 0; (i < pCD->numInhabited) && !rval; i++)
1787 if (pWS->id == pCD->pWsList[i].wsID)
1795 } /* END OF FUNCTION ClientInWorkspace */
1798 /*************************************<->*************************************
1800 * GetWsClientData (pWS, pCD)
1805 * This function returns a pointer to the client's specific data for
1810 * pWS = pointer to workspace data
1811 * pCD = pointer to client data
1815 * The function returns a pointer to the client's data for this
1816 * workspace. If the client isn't in the workspace, an error is
1817 * printed and the first datum in the workspace list is returned.
1819 *************************************<->***********************************/
1823 WmWorkspaceData *pWS,
1828 WsClientData *pWsc = NULL;
1830 for (i = 0; (i < pCD->numInhabited) && !pWsc; i++)
1832 if (pWS->id == pCD->pWsList[i].wsID)
1834 pWsc = &pCD->pWsList[i];
1840 pWsc = &pCD->pWsList[0];
1845 } /* END OF FUNCTION GetWsClientData */
1848 /*************************************<->*************************************
1850 * SetClientWsIndex (pCD)
1855 * This function sets the index into the client's array of workspace
1856 * specific data. This index points to the data to be used for the
1857 * currently active workspace.
1861 * pCD = pointer to client data
1865 * The function returns an index as described above. If the client is
1866 * not in the currently active workspace, then the index returned is 0.
1868 *************************************<->***********************************/
1876 WmWorkspaceData *pWS = pCD->pSD->pActiveWS;
1878 for (i = 0; (i < pCD->numInhabited); i++)
1880 if (pWS->id == pCD->pWsList[i].wsID)
1886 if (i >= pCD->numInhabited)
1891 pCD->currentWsc = i;
1893 } /* END OF FUNCTION SetClientWsIndex */
1897 /*************************************<->*************************************
1899 * ProcessWmWorkspaceHints (pCD)
1904 * This function processes a change to the _DT_WORKSPACE_HINTS property
1905 * on a window that we manage.
1909 * pCD = pointer to client data
1913 * Returns False if we ran out of memory or no hints.
1914 * Returns True on success.
1916 *************************************<->***********************************/
1919 ProcessWorkspaceHints(
1925 unsigned int numIDs;
1926 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
1927 Boolean rval = False;
1931 WorkspaceID *pDiff = NULL;
1934 numOld = pCD->numInhabited;
1935 ReserveIdListSpace (numOld);
1936 for (i = 0; i < numOld; i++)
1938 pResIDs[i] = pCD->pWsList[i].wsID;
1941 if ((pCD->client) &&
1942 (GetWorkspaceHints (DISPLAY, pCD->client,
1943 &pIDs, &numIDs, &bAll) == Success) &&
1944 (bAll || (numIDs && (pDiff = (WorkspaceID *)
1945 XtMalloc (sizeof(WorkspaceID) * MAX(numIDs, numOld))))))
1948 * Process request to put window in all workspaces
1950 pCD->putInAll = bAll;
1951 CheckForPutInAllRequest (pCD, pIDs, numIDs);
1956 * Compute the ids to be removed.
1960 for (i=0; i < numOld; i++)
1963 for (j=0; j < numIDs; j++)
1965 if (pIDs[j] == pResIDs[i])
1974 pDiff[numDiff++] = pResIDs[i];
1979 * Remove the client from the set of workspaces
1983 RemoveClientFromWorkspaces (pCD, pDiff, numDiff);
1988 * Process request to put window in all workspaces
1993 for (i=0; i<pCD->pSD->numWorkspaces; i++)
1995 if (!ClientInWorkspace(&pCD->pSD->pWS[i], pCD))
1997 AddClientToWorkspaces (pCD, &pCD->pSD->pWS[i].id, 1);
2004 * Compute the ids to be added.
2008 for (i=0; i < numIDs; i++)
2011 for (j=0; j < numOld; j++)
2013 if (pResIDs[j] == pIDs[i])
2022 pDiff[numDiff++] = pIDs[i];
2027 * Add the client to the set of workspaces
2031 AddClientToWorkspaces (pCD, pDiff, numDiff);
2036 * If the client is not in any workspaces, then
2037 * put it in the current one
2039 * !!! Is this right? !!!
2041 if (pCD->numInhabited == 0)
2043 AddClientToWorkspaces (pCD, &pSD->pActiveWS->id, 1);
2047 * Free up the old list of hints
2049 if (pCD->pWorkspaceHints)
2051 XFree ((char *)pCD->pWorkspaceHints);
2055 XtFree ((char *)pDiff);
2059 * Save the new hints
2061 pCD->pWorkspaceHints = pIDs;
2062 pCD->numWorkspaceHints = numIDs;
2065 * Update the presence property
2067 UpdateWorkspacePresenceProperty (pCD);
2073 } /* END OF FUNCTION ProcessWorkspaceHints */
2076 /*************************************<->*************************************
2078 * InsureUniqueWorkspaceHints (pCD)
2083 * This function processes the workspace hints and removes duplicates.
2087 * pCD = pointer to client data
2091 * May modify *pWorkspaceHints and numWorkspaceHints
2093 *************************************<->***********************************/
2096 InsureUniqueWorkspaceHints(
2105 if (pCD->numWorkspaceHints < 2) return;
2107 pID = pCD->pWorkspaceHints;
2112 while (next < pCD->numWorkspaceHints)
2115 for (i = 0; i < next; i++)
2117 if (pID [next] == pID [i])
2119 /* duplicate found! */
2127 /* skip duplicates */
2132 /* not a duplicate */
2137 * We need to copy up over an old duplicate
2139 pID [trail] = pID [next];
2145 pCD->numWorkspaceHints = trail+1;
2147 } /* END OF FUNCTION InsureUniqueWorkspaceHints */
2151 /*************************************<->*************************************
2153 * ProcessWorkspaceHintList (pCD, pIDs, numIDs)
2158 * This function processes a list of workspace hints for a client.
2162 * pCD = pointer to client data
2163 * pIDs = pointer to a list of workspace IDs
2164 * numIDs = number of IDs in the list
2169 *************************************<->***********************************/
2172 ProcessWorkspaceHintList(
2175 unsigned int numIDs )
2179 WmWorkspaceData *pWS;
2185 * Keep these hints; make sure there are no duplicate
2186 * workspace requests.
2188 pCD->pWorkspaceHints = pIDs;
2189 pCD->numWorkspaceHints = numIDs;
2190 InsureUniqueWorkspaceHints (pCD);
2191 numIDs = pCD->numWorkspaceHints;
2193 if (pCD->pWorkspaceHints)
2196 * Process request to put window in all workspaces
2198 CheckForPutInAllRequest (pCD, pIDs, numIDs);
2202 for (i=0; i<pCD->pSD->numWorkspaces; i++)
2204 PutClientIntoWorkspace (&pCD->pSD->pWS[i], pCD);
2209 for (i=0; i<numIDs; i++)
2212 * Put the client into requested workspaces that
2215 if ((pWS = GetWorkspaceData (pCD->pSD,
2216 pCD->pWorkspaceHints[i])))
2218 PutClientIntoWorkspace (pWS, pCD);
2225 } /* END OF FUNCTION ProcessWorkspaceHintList */
2228 /*************************************<->*************************************
2230 * RemoveSingleClientFromWorkspaces (pCD, pIDs, numIDs)
2235 * This function removes a single client from a list of workspaces
2239 * pCD = pointer to client data
2240 * pIDs = pointer to a list of workspace IDs
2241 * numIDs = number of workspace IDs
2246 *************************************<->***********************************/
2249 RemoveSingleClientFromWorkspaces(
2252 unsigned int numIDs )
2256 WmWorkspaceData *pWS;
2258 for (i=0; i < numIDs; i++)
2261 * Remove the client from the specified workspaces
2263 if ((pWS = GetWorkspaceData (pCD->pSD, pIDs[i])) &&
2264 (ClientInWorkspace (pWS, pCD)))
2267 * If this workspace is active, then make the
2268 * window unseen. We only need to call
2269 * SetClientState on the main window, the
2270 * transients will get taken care of in there.
2272 if ((pWS == pCD->pSD->pActiveWS) &&
2273 (pCD->transientLeader == NULL) &&
2274 !(pCD->clientState & UNSEEN_STATE))
2276 SetClientState (pCD,
2277 (pCD->clientState | UNSEEN_STATE), CurrentTime);
2279 TakeClientOutOfWorkspace (pWS, pCD);
2282 * Update the presence property
2284 UpdateWorkspacePresenceProperty (pCD);
2288 } /* END OF FUNCTION RemoveSingleClientFromWorkspaces */
2290 /*************************************<->*************************************
2292 * RemoveSubtreeFromWorkspaces (pCD, pIDs, numIDs)
2297 * This function removes a transient subtree from a list of workspaces
2301 * pCD = pointer to client data
2302 * pIDs = pointer to a list of workspace IDs
2303 * numIDs = number of workspace IDs
2308 *************************************<->***********************************/
2311 RemoveSubtreeFromWorkspaces(
2314 unsigned int numIDs )
2319 pNext = pCD->transientChildren;
2322 /* process all children first */
2323 if (pNext->transientChildren)
2325 RemoveSubtreeFromWorkspaces (pNext, pIDs, numIDs);
2329 RemoveSingleClientFromWorkspaces (pNext, pIDs, numIDs);
2331 pNext = pNext->transientSiblings;
2334 /* process the primary window */
2335 RemoveSingleClientFromWorkspaces (pCD, pIDs, numIDs);
2338 } /* END OF FUNCTION RemoveSubtreeFromWorkspaces */
2342 /******************************<->*************************************
2344 * pIDs = GetListOfOccupiedWorkspaces (pCD, numIDs)
2349 * This function creates a list of occupied workspaces of a particular
2350 * client, EXCLUDING the current workspace.
2354 * pCD = pointer to client data
2358 * pIDs = pointer to a list of workspace IDs
2359 * numIDs = number of workspace IDs
2363 * memory for pIDs is allocated with XtMalloc and should be
2364 * freed with XtFree.
2367 ******************************<->***********************************/
2369 GetListOfOccupiedWorkspaces(
2375 WorkspaceID *pLocalIDs = NULL;
2377 WorkspaceID activeWsID = pCD->pSD->pActiveWS->id;
2381 if ((pLocalIDs = (WorkspaceID *) XtMalloc (pCD->numInhabited *
2382 sizeof(WorkspaceID))) == NULL)
2384 Warning (((char *)GETMESSAGE(76, 7, "Insufficient memory")));
2388 for (i = 0; i < pCD->numInhabited; i++)
2390 if (activeWsID != pCD->pWsList[i].wsID)
2392 pLocalIDs[(*numIDs)++] = pCD->pWsList[i].wsID;
2398 } /* END OF FUNCTION GetListOfOccupiedWorkspaces */
2401 /******************************<->*************************************
2403 * HonorAbsentMapBehavior(pCD)
2408 * This function adds a client to the current workspace and
2409 * if (pCD->absentMapBehavior == AMAP_BEHAVIOR_MOVE)
2410 * removes the client from the other workspaces
2415 * pCD = pointer to client data
2420 ******************************<->***********************************/
2423 HonorAbsentMapBehavior(
2426 int inWorkspace = 0;
2428 if (pCD->absentMapBehavior == AMAP_BEHAVIOR_MOVE)
2433 * Remove from other workspaces
2435 for (wsCnt = 0; wsCnt < pCD->numInhabited; wsCnt = inWorkspace)
2437 if (pCD->pWsList[wsCnt].wsID != pCD->pSD->pActiveWS->id)
2439 RemoveClientFromWorkspaces (pCD,
2440 &pCD->pWsList[wsCnt].wsID, 1);
2446 if (inWorkspace == 0)
2447 AddClientToWorkspaces (pCD, &ACTIVE_WS->id, 1);
2449 } /* END OF FUNCTION HonorAbsentMapBehavior */
2453 /******************************<->*************************************
2455 * RemoveClientFromWorkspaces (pCD, pIDs, numIDs)
2460 * This function removes a client from a list of workspaces
2464 * pCD = pointer to client data
2465 * pIDs = pointer to a list of workspace IDs
2466 * numIDs = number of workspace IDs
2471 ******************************<->***********************************/
2474 RemoveClientFromWorkspaces(
2477 unsigned int numIDs )
2480 ClientData *pcdLeader;
2482 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
2484 RemoveSubtreeFromWorkspaces (pcdLeader, pIDs, numIDs);
2487 } /* END OF FUNCTION RemoveClientFromWorkspaces */
2490 /*************************************<->*************************************
2492 * AddSingleClientToWorkspaces (pCD, pIDs, numIDs)
2497 * This function adds a single client to a list of workspaces
2501 * pCD = pointer to client data
2502 * pIDs = pointer to a list of workspace IDs
2503 * numIDs = number of workspace IDs
2508 *************************************<->***********************************/
2511 AddSingleClientToWorkspaces(
2514 unsigned int numIDs )
2518 WmWorkspaceData *pWS;
2520 for (i=0; i < numIDs; i++)
2523 * Add the client to the specified workspaces if
2524 * it is not already there.
2526 if ((pWS = GetWorkspaceData (pCD->pSD, pIDs[i])) &&
2527 (!ClientInWorkspace (pWS, pCD)))
2529 PutClientIntoWorkspace (pWS, pCD);
2531 if ((pWS == PSD_FOR_CLIENT(pCD)->pActiveWS) &&
2532 (pCD->transientLeader == NULL) &&
2533 (pCD->clientState & UNSEEN_STATE))
2535 SetClientState (pCD,
2536 (pCD->clientState & ~UNSEEN_STATE), CurrentTime);
2540 * Update the presence property (only on transient leader)
2542 UpdateWorkspacePresenceProperty (pCD);
2546 } /* END OF FUNCTION AddSingleClientToWorkspace */
2549 /*************************************<->*************************************
2551 * AddSubtreeToWorkspaces (pCD, pIDs, numIDs)
2556 * This function adds a client subtree to a list of workspaces
2560 * pCD = pointer to client data (head of subtree)
2561 * pIDs = pointer to a list of workspace IDs
2562 * numIDs = number of workspace IDs
2567 *************************************<->***********************************/
2570 AddSubtreeToWorkspaces(
2573 unsigned int numIDs )
2578 pNext = pCD->transientChildren;
2581 /* process all children first */
2582 if (pNext->transientChildren)
2584 AddSubtreeToWorkspaces (pNext, pIDs, numIDs);
2588 AddSingleClientToWorkspaces (pNext, pIDs, numIDs);
2590 pNext = pNext->transientSiblings;
2593 /* process the primary window */
2594 AddSingleClientToWorkspaces (pCD, pIDs, numIDs);
2597 } /* END OF FUNCTION AddSubtreeToWorkspaces */
2600 /*************************************<->*************************************
2602 * AddClientToWorkspaces (pCD, pIDs, numIDs)
2607 * This function adds a transient tree to a list of workspaces
2611 * pCD = pointer to client data
2612 * pIDs = pointer to a list of workspace IDs
2613 * numIDs = number of workspace IDs
2618 *************************************<->***********************************/
2621 AddClientToWorkspaces(
2624 unsigned int numIDs )
2627 ClientData *pcdLeader;
2629 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
2631 AddSubtreeToWorkspaces (pcdLeader, pIDs, numIDs);
2633 } /* END OF FUNCTION AddClientToWorkspaces */
2637 /*************************************<->*************************************
2639 * AddClientToWsList (pWS, pCD)
2644 * This function adds a client to a list of clients in a workspace
2648 * pCD = pointer to client data
2649 * pWS = pointer to workspace data
2655 *************************************<->***********************************/
2659 WmWorkspaceData *pWS,
2663 if (pWS->numClients >= pWS->sizeClientList)
2665 if (pWS->sizeClientList == 0)
2667 pWS->ppClients = (ClientData **)
2668 XtMalloc (WINDOW_ALLOC_AMOUNT * sizeof(ClientData *));
2672 pWS->ppClients = (ClientData **)
2673 XtRealloc ((char *)pWS->ppClients,
2674 (pWS->sizeClientList + WINDOW_ALLOC_AMOUNT) *
2675 sizeof(ClientData *));
2678 if (!pWS->ppClients)
2680 Warning (((char *)GETMESSAGE(76, 9, "Insufficient memory to add window to workspace")));
2681 ExitWM(WM_ERROR_EXIT_VALUE);
2684 pWS->sizeClientList += WINDOW_ALLOC_AMOUNT;
2687 if (pWS->numClients < pWS->sizeClientList)
2689 pWS->ppClients[pWS->numClients] = pCD;
2692 } /* END OF FUNCTION AddClientToWsList */
2695 /*************************************<->*************************************
2697 * RemoveClientFromWsList (pWS, pCD)
2702 * This function removes a client from a list of clients in a workspace
2706 * pCD = pointer to client data
2707 * pWS = pointer to workspace data
2713 *************************************<->***********************************/
2716 RemoveClientFromWsList(
2717 WmWorkspaceData *pWS,
2723 for (dest = 0; dest < pWS->numClients; dest++)
2725 if (pWS->ppClients[dest] == pCD)
2731 for (src = dest+1; src < pWS->numClients; src++, dest++)
2733 pWS->ppClients[dest] = pWS->ppClients[src];
2738 } /* END OF FUNCTION RemoveClientFromWsList */
2741 /*************************************<->*************************************
2744 * F_CreateWorkspace (args, pCD, event)
2762 *************************************<->***********************************/
2771 WmScreenData *pSD = ACTIVE_PSD;
2773 if (pSD->numWorkspaces >= MAX_WORKSPACE_COUNT)
2775 char buffer[MAXWMPATH];
2777 * At the maximum number of allowed workspaces.
2780 ((char *)GETMESSAGE(76, 14, "Maximum number of workspaces is %d. New workspace was not created.")), MAX_WORKSPACE_COUNT);
2785 CreateWorkspace (ACTIVE_PSD, (unsigned char *)args);
2790 } /* END OF FUNCTION F_CreateWorkspace */
2793 /*************************************<->*************************************
2796 * F_DeleteWorkspace (args, pCD, event)
2814 *************************************<->***********************************/
2823 WmScreenData *pSD = ACTIVE_PSD;
2824 WmWorkspaceData *pWS = NULL;
2833 for (i=0; i<pSD->numWorkspaces; i++)
2835 if (!strcmp(pSD->pWS[i].name, args))
2837 pWS = &(pSD->pWS[i]);
2844 DeleteWorkspace (pWS);
2848 } /* END OF FUNCTION F_DeleteWorkspace */
2851 /*************************************<->*************************************
2854 * F_GotoWorkspace (args, pCD, event)
2872 *************************************<->***********************************/
2882 WmWorkspaceData *pWS;
2884 wsID = XInternAtom (DISPLAY, args, False);
2885 pWS = GetWorkspaceData (ACTIVE_PSD, wsID);
2889 ChangeToWorkspace (pWS);
2893 } /* END OF FUNCTION F_GotoWorkspace */
2898 /*************************************<->*************************************
2901 * F_AddToAllWorkspaces (args, pCD, event)
2906 * Puts a client into all workspaces
2912 * pCD = pointer to client data
2923 * The list of Ids returned has been privately allocated. Copy
2924 * if you want to save or do anything with it.
2926 *************************************<->***********************************/
2929 F_AddToAllWorkspaces(
2938 if (pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS))
2942 ReserveIdListSpace (pSD->numWorkspaces);
2944 for (i = 0; i < pSD->numWorkspaces; i++)
2946 pResIDs[i] = pSD->pWS[i].id;
2949 AddClientToWorkspaces (pCD, pResIDs, pSD->numWorkspaces);
2951 pCD->putInAll = True;
2956 } /* END OF FUNCTION F_AddToAllWorkspaces */
2959 /*************************************<->*************************************
2962 * F_Remove (args, pCD, event)
2967 * Removes a client from the current workspace
2973 * pCD = pointer to client data
2985 *************************************<->***********************************/
2994 Boolean rval = False;
2997 * Only remove if in more than one workspace.
2999 if ((pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS)) &&
3000 (pCD->numInhabited > 1))
3002 if (ClientInWorkspace (ACTIVE_WS, pCD))
3004 RemoveClientFromWorkspaces (pCD, &ACTIVE_WS->id, 1);
3005 pCD->putInAll = False;
3011 } /* END OF FUNCTION F_Remove */
3015 /*************************************<->*************************************
3017 * GetCurrentWorkspaceIndex (pSD)
3022 * Returns an index into the screens array of workspace structures
3023 * for the current workspace.
3036 *************************************<->***********************************/
3038 GetCurrentWorkspaceIndex(
3044 for (i = 0 ; i < pSD->numWorkspaces; i++)
3046 if (pSD->pWS[i].id == pSD->pActiveWS->id)
3050 if (i >= pSD->numWorkspaces)
3052 /* failed to find workspace!!! How did that happen??? */
3055 Warning ("Failed to find workspace index");
3060 } /* END OF FUNCTION GetCurrentWorkspaceIndex */
3063 /*************************************<->*************************************
3066 * InsureIconForWorkspace (pWS, pCD)
3071 * Makes sure an icon exists for the workspace
3084 *************************************<->***********************************/
3087 InsureIconForWorkspace(
3088 WmWorkspaceData *pWS,
3094 if (pCD->clientFunctions & MWM_FUNC_MINIMIZE)
3096 pWsc = GetWsClientData (pWS, pCD);
3098 if ((pCD->pSD->useIconBox) &&
3099 (!(pCD->clientFlags & (CLIENT_WM_CLIENTS | FRONT_PANEL_BOX))))
3102 * Create a new widget for the icon box
3104 if (MakeIcon (pWS, pCD))
3106 XSaveContext (DISPLAY, pWsc->iconFrameWin,
3107 wmGD.windowContextType, (caddr_t)pCD);
3109 if (pCD->iconWindow && pWsc->iconFrameWin)
3111 XGrabButton (DISPLAY, AnyButton, AnyModifier,
3112 pWsc->iconFrameWin, True,
3113 ButtonPressMask|ButtonReleaseMask|
3115 GrabModeAsync, GrabModeAsync, None,
3116 wmGD.workspaceCursor);
3119 ShowClientIconState (pCD, (pCD->clientState & ~UNSEEN_STATE));
3125 * Reuse existing icon in new workspaces. Suggest
3126 * icon position in current WS as position of icon
3129 pWsc->iconFrameWin = pCD->pWsList[0].iconFrameWin;
3130 pWsc->iconX = ICON_X(pCD);
3131 pWsc->iconY = ICON_Y(pCD);
3133 if ((pCD->clientState & ~UNSEEN_STATE) != MINIMIZED_STATE)
3135 pWsc->iconPlace = NO_ICON_PLACE;
3137 else if (!wmGD.iconAutoPlace)
3139 if (wmGD.positionIsFrame)
3141 pWsc->iconX -= pCD->clientOffset.x;
3142 pWsc->iconY -= pCD->clientOffset.y;
3144 PlaceIconOnScreen (pCD, &pWsc->iconX, &pWsc->iconY);
3146 else /* icon auto placement */
3149 CvtIconPositionToPlace (&pWS->IPData,
3150 pWsc->iconX, pWsc->iconY);
3151 if (pWS->IPData.placeList[pWsc->iconPlace].pCD)
3153 /* The spot is already occupied! Find a
3156 FindIconPlace (pCD, &pWS->IPData, pWsc->iconX,
3159 if (pWsc->iconPlace == NO_ICON_PLACE)
3161 /* Can't find a spot close by. Use the
3162 next available slot */
3163 pWsc->iconPlace = GetNextIconPlace (&pWS->IPData);
3164 if (pWsc->iconPlace == NO_ICON_PLACE)
3167 CvtIconPositionToPlace (&pWS->IPData,
3173 CvtIconPlaceToPosition (&pWS->IPData, pWsc->iconPlace,
3174 &pWsc->iconX, &pWsc->iconY);
3177 if (!(pWS->IPData.placeList[pWsc->iconPlace].pCD))
3179 pWS->IPData.placeList[pWsc->iconPlace].pCD = pCD;
3184 } /* END OF FUNCTION InsureIconForWorkspace */
3187 /*************************************<->*************************************
3190 * GetLeaderPresence (pCD, pIDs, pnumIDs)
3195 * Gets the workspace presence of the transient tree leader for a
3201 * pCD = pointer to client data
3202 * ppIDs = pointer to pointer to list of workspace ids
3203 * pnumIDs = pointer to number of workspace ids
3208 * *ppIDS = list of workspace IDs
3209 * *pnumIDs = number of workspace IDs in list
3211 * Return = true on success
3216 * ID list is dynamically allocated, please XtFree() it when you're
3219 *************************************<->***********************************/
3224 WorkspaceID **ppIDs,
3225 unsigned int *pnumIDs )
3228 ClientData *pcdLeader;
3230 Boolean rval = False;
3231 WorkspaceID *pLocalIDs;
3233 if ((pLocalIDs = (WorkspaceID *) XtMalloc (pCD->pSD->numWorkspaces *
3234 sizeof(WorkspaceID))) == NULL)
3236 Warning (((char *)GETMESSAGE(76, 10, "Insufficient Memory (GetLeaderPresence)")));
3237 ExitWM (WM_ERROR_EXIT_VALUE);
3241 * Make up list of workspaces for primary window
3243 if (pCD->transientLeader)
3245 pcdLeader = FindTransientTreeLeader (pCD);
3247 for (i = 0; i < pcdLeader->numInhabited; i++)
3249 pLocalIDs[i] = pcdLeader->pWsList[i].wsID;
3253 *pnumIDs = pcdLeader->numInhabited;
3259 } /* END OF FUNCTION GetLeaderPresence */
3262 /*************************************<->*************************************
3265 * GetMyOwnPresence (pCD, pIDs, pnumIDs)
3270 * Returns the current workspace presence for the client
3275 * pCD = pointer to client data
3276 * ppIDs = pointer to pointer to list of workspace ids
3277 * pnumIDs = pointer to number of workspace ids
3282 * *ppIDS = list of workspace IDs
3283 * *pnumIDs = number of workspace IDs in list
3285 * Return = true on success
3290 * ID list is dynamically allocated (by DtWsmGetWorkspacesOccupied).
3291 * Please XtFree() it when you're done.
3293 *************************************<->***********************************/
3298 WorkspaceID **ppIDs,
3299 unsigned int *pnumIDs )
3302 Boolean rval = False;
3303 unsigned long nIDs = (unsigned long)*pnumIDs;
3306 * Get the workspace presence property
3310 (HasProperty (pCD, wmGD.xa_DT_WORKSPACE_PRESENCE) ||
3312 XmInternAtom (DISPLAY, _XA_VUE_WORKSPACE_PRESENCE,
3315 HasProperty (pCD, wmGD.xa_DT_WORKSPACE_PRESENCE)
3317 && (DtWsmGetWorkspacesOccupied (DISPLAY, pCD->client, ppIDs,
3325 *pnumIDs = (unsigned int)nIDs;
3329 } /* END OF FUNCTION GetMyOwnPresence */
3333 /*************************************<->*************************************
3336 * ReserveIdListSpace (numIDs)
3341 * Insures that there is enough room in our privately allocated
3342 * list of workspace IDs
3347 * numIDs = number of workspace ids
3354 *************************************<->***********************************/
3363 pResIDs = (WorkspaceID *)
3364 XtMalloc (numIDs * sizeof (WorkspaceID));
3370 else if (numResIDs < numIDs)
3372 pResIDs = (WorkspaceID *) XtRealloc ((char *)pResIDs,
3373 numIDs * sizeof (WorkspaceID));
3375 numResIDs = (pResIDs)? numIDs : 0;
3378 if (pResIDs == NULL)
3380 Warning (((char *)GETMESSAGE(76, 11, "Insufficient memory")));
3381 ExitWM (WM_ERROR_EXIT_VALUE);
3384 } /* END OF FUNCTION ReserveIdListSpace */
3389 /******************************<->*************************************
3391 * SaveResources (pSD)
3395 * Saves dtwm resources to restore session
3399 * pSD = pointer to screen data
3408 *************************************<->***********************************/
3410 SaveResources( WmScreenData *pSD)
3413 WmPanelistObject pPanelist;
3419 SaveWorkspaceResources(pSD->pActiveWS,
3420 (WM_RES_INITIAL_WORKSPACE |
3421 WM_RES_WORKSPACE_COUNT));
3424 pPanelist = (WmPanelistObject) pSD->wPanelist;
3425 if (pPanelist && O_Shell(pPanelist))
3427 /* This is the front panel for the screen */
3428 SaveWorkspaceResources(pSD->pActiveWS,
3429 WM_RES_FP_POSITION);
3432 /* Call the fronto panel function to save its resources */
3434 WmFrontPanelSessionSaveData();
3439 for (wsCnt = 0; wsCnt < pSD->numWorkspaces; wsCnt++)
3443 SaveWorkspaceResources(&pSD->pWS[wsCnt],
3444 WM_RES_ICONBOX_GEOMETRY);
3448 SaveHelpResources(pSD);
3452 } /* END OF FUNCTION SaveResources */
3455 /******************************<->*************************************
3457 * SaveWorkspaceResource (pWS, flags)
3461 * Modifies the RESOURCE_MANAGER property to add update versions
3462 * of the requested resources.
3466 * pWS = pointer to workspace data
3475 *************************************<->***********************************/
3477 SaveWorkspaceResources(
3478 WmWorkspaceData *pWS,
3479 unsigned long flags)
3481 char *buffer = NULL;
3482 int bufferLength = 0;
3487 char screenName[1024];
3488 char tmpScreenName[10];
3492 Dimension clientWidth;
3493 Dimension clientHeight;
3495 WmPanelistObject pPanelist = (WmPanelistObject) pWS->pSD->wPanelist;
3496 ClientData *pCD_Panel ;
3497 char tmpBuffer[MAXWMPATH+1];
3500 /* allocate initial data space */
3501 if ((data = (char *) XtMalloc (MAXWMPATH+1)) == NULL)
3504 GETMESSAGE(76,12,"Insufficient memory to save resources")));
3505 Do_Quit_Mwm (False);
3510 if (bufferLength == 0)
3512 buffer = (char *) XtMalloc (MAXWMPATH+1);
3513 bufferLength = MAXWMPATH;
3517 /* Get our current resource class */
3521 res_class = WM_RESOURCE_CLASS;
3525 res_class = DT_WM_RESOURCE_CLASS;
3528 strcpy(screenName, "*");
3529 strcat(screenName,XtName (pWS->pSD->screenTopLevelW));
3531 /* construct and write out the resources specification */
3533 if (flags & WM_RES_BACKDROP_IMAGE)
3535 iLen = (strlen (res_class) + strlen (screenName) +
3536 strlen (pWS->name) + strlen (WmNbackdrop) +
3537 strlen (WmNimage) + strlen (pWS->backdrop.image) + 20);
3539 if (iLen > bufferLength)
3541 bufferLength += iLen;
3543 XtRealloc (buffer, bufferLength * sizeof(char));
3546 sprintf (buffer, "%s%s*%s*%s*%s: %s\n", res_class,
3547 screenName, pWS->name,
3548 WmNbackdrop, WmNimage, pWS->backdrop.image);
3550 AddStringToResourceData (buffer, &data, &cum_len);
3554 if (flags & WM_RES_WORKSPACE_TITLE)
3558 asciiName = WmXmStringToString (pWS->title);
3560 iLen = strlen (res_class) + strlen (screenName) +
3561 strlen (pWS->name) + strlen (WmNtitle) +
3562 strlen (asciiName) + 16;
3564 if (iLen > bufferLength)
3566 bufferLength += iLen;
3568 XtRealloc (buffer, bufferLength * sizeof(char));
3571 sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
3572 screenName, pWS->name,
3573 WmNtitle, asciiName);
3575 AddStringToResourceData (buffer, &data, &cum_len);
3580 if ((flags & WM_RES_INITIAL_WORKSPACE) &&
3581 (!wmGD.useStandardBehavior))
3583 iLen = strlen (res_class) + strlen (screenName) +
3584 strlen (WmNinitialWorkspace) + strlen (pWS->name) + 14;
3586 if (iLen > bufferLength)
3588 bufferLength += iLen;
3590 XtRealloc (buffer, bufferLength * sizeof(char));
3593 sprintf (buffer, "%s%s*%s: %s\n", res_class,
3595 WmNinitialWorkspace, pWS->name);
3597 AddStringToResourceData (buffer, &data, &cum_len);
3600 if ((flags & WM_RES_WORKSPACE_LIST) &&
3601 (!wmGD.useStandardBehavior))
3603 WmWorkspaceData *pWSi;
3607 pWSi = pWS->pSD->pWS;
3609 pchQname = (char *) _DtWmParseMakeQuotedString (
3610 (unsigned char *)pWSi->name);
3611 strcpy ((char *)wmGD.tmpBuffer, pchQname);
3616 for (i=1; i<pWS->pSD->numWorkspaces; i++, pWSi++)
3618 strcat ((char *)wmGD.tmpBuffer, " ");
3619 pchQname = (char *) _DtWmParseMakeQuotedString (
3620 (unsigned char *)pWSi->name);
3621 strcat ((char *)wmGD.tmpBuffer, pchQname);
3625 sprintf (buffer, "%s%s*%s: %s\n", res_class,
3627 WmNworkspaceList, wmGD.tmpBuffer);
3629 AddStringToResourceData (buffer, &data, &cum_len);
3632 if ((flags & WM_RES_WORKSPACE_COUNT) &&
3633 (!wmGD.useStandardBehavior))
3637 sprintf (pchNumWs, "%d", pWS->pSD->numWorkspaces);
3639 iLen = strlen (res_class) + strlen (screenName) +
3640 strlen (WmNworkspaceCount) + strlen (pchNumWs) + 14;
3642 if (iLen > bufferLength)
3644 bufferLength += iLen;
3646 XtRealloc (buffer, bufferLength * sizeof(char));
3649 sprintf (buffer, "%s%s*%s: %s\n", res_class,
3651 WmNworkspaceCount, pchNumWs);
3653 AddStringToResourceData (buffer, &data, &cum_len);
3656 if ((flags & WM_RES_FP_POSITION) &&
3657 (O_Shell(pPanelist)) &&
3658 (!wmGD.useStandardBehavior) &&
3659 (!XFindContext (DISPLAY, XtWindow(O_Shell(pPanelist)),
3660 wmGD.windowContextType,
3661 (XtPointer)&pCD_Panel)))
3663 Position midX, midY, tmpX, tmpY;
3664 Dimension screenWidth, screenHeight;
3666 clientX = pCD_Panel->clientX;
3667 clientY = pCD_Panel->clientY;
3670 * Determine quadrant that the front panel midpoint is
3671 * in and save front panel with appropriate gravity.
3674 /* find panel midpoint */
3676 midX = clientX+(pCD_Panel->clientWidth >> 1);
3677 midY = clientY+(pCD_Panel->clientHeight >> 1);
3679 /* get screen dimensions */
3681 screenWidth = XDisplayWidth (DISPLAY, pCD_Panel->pSD->screen);
3682 screenHeight = XDisplayHeight (DISPLAY, pCD_Panel->pSD->screen);
3685 * Determine midpoint quadrant and set up client geometry
3686 * relative to that corner. Adjust if positionIsFrame
3689 if (midX <= (Position) screenWidth/2)
3691 if(wmGD.positionIsFrame)
3693 clientX -= pCD_Panel->frameInfo.upperBorderWidth;
3697 if (midY <= (Position) screenHeight/2)
3700 if(wmGD.positionIsFrame)
3702 clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
3703 pCD_Panel->frameInfo.titleBarHeight);
3705 sprintf (tmpBuffer, "+%d+%d", clientX, clientY);
3710 clientY = screenHeight - clientY - pCD_Panel->clientHeight;
3711 if(wmGD.positionIsFrame)
3713 clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
3716 sprintf (tmpBuffer, "+%d-%d", clientX, clientY);
3721 clientX = screenWidth - clientX - pCD_Panel->clientWidth;
3722 if (wmGD.positionIsFrame)
3724 clientX -= pCD_Panel->frameInfo.lowerBorderWidth;
3728 if (midY <= (Position) screenHeight/2)
3731 if(wmGD.positionIsFrame)
3733 clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
3734 pCD_Panel->frameInfo.titleBarHeight);
3736 sprintf (tmpBuffer, "-%d+%d", clientX, clientY);
3741 clientY = screenHeight - clientY - pCD_Panel->clientHeight;
3742 if(wmGD.positionIsFrame)
3744 clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
3746 sprintf (tmpBuffer, "-%d-%d", clientX, clientY);
3750 iLen = strlen (res_class) + strlen (screenName) +
3751 strlen (XtName(O_Shell(pPanelist))) +
3752 strlen (WmNgeometry) + strlen (tmpBuffer) + 18;
3754 if (iLen > bufferLength)
3756 bufferLength += iLen;
3758 XtRealloc (buffer, bufferLength * sizeof(char));
3761 sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
3763 XtName (O_Shell(pPanelist)),
3764 WmNgeometry, tmpBuffer);
3766 AddStringToResourceData (buffer, &data, &cum_len);
3769 if ((flags & WM_RES_ICONBOX_GEOMETRY) &&
3770 (!wmGD.useStandardBehavior))
3772 /* update iconbox geometry string */
3774 if (pWS->iconBoxGeometry)
3776 XtFree((char *) (pWS->iconBoxGeometry));
3777 pWS->iconBoxGeometry = NULL;
3780 clientWidth = (pWS->pIconBox->pCD_iconBox->clientWidth -
3781 pWS->pIconBox->pCD_iconBox->baseWidth) /
3782 pWS->pIconBox->pCD_iconBox->widthInc;
3784 clientHeight = (pWS->pIconBox->pCD_iconBox->clientHeight -
3785 pWS->pIconBox->pCD_iconBox->baseHeight) /
3786 pWS->pIconBox->pCD_iconBox->heightInc ;
3788 if(wmGD.positionIsFrame)
3790 CalculateGravityOffset (pWS->pIconBox->pCD_iconBox, &xoff, &yoff);
3791 clientX = pWS->pIconBox->pCD_iconBox->clientX - xoff;
3792 clientY = pWS->pIconBox->pCD_iconBox->clientY - yoff;
3796 clientX = pWS->pIconBox->pCD_iconBox->clientX;
3797 clientY = pWS->pIconBox->pCD_iconBox->clientY;
3800 sprintf (buffer, "%dx%d+%d+%d", clientWidth, clientHeight,
3803 pWS->iconBoxGeometry = strdup( buffer);
3805 iLen = strlen (res_class) + strlen (screenName) +
3806 strlen (pWS->name) + strlen (WmNiconBoxGeometry) +
3807 strlen (pWS->iconBoxGeometry) + 18;
3809 if (iLen > bufferLength)
3811 bufferLength += iLen;
3813 XtRealloc (buffer, bufferLength * sizeof(char));
3816 sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
3817 screenName, pWS->name,
3818 WmNiconBoxGeometry, pWS->iconBoxGeometry);
3820 AddStringToResourceData (buffer, &data, &cum_len);
3827 * Merge in the resource(s)
3829 _DtAddToResource (DISPLAY, data);
3835 } /* END OF FUNCTION SaveWorkspaceResources */
3838 /******************************<->*************************************
3840 * AddStringToResourceData (string, pdata, plen)
3844 * Adds a string to a growing buffer of strings.
3848 * string - string to add
3849 * pdata - pointer to data pointer
3850 * plen - number of bytes used in *pdata already
3854 * *pdata - data pointer (may be changed by XtRealloc)
3855 * *plen - number of bytes used in *pdata (old value plus length
3861 *************************************<->***********************************/
3863 AddStringToResourceData(
3868 if ((*pdata = (char *) XtRealloc(*pdata, *plen+strlen(string)+1)) == NULL)
3870 Warning (((char *)GETMESSAGE(76, 13, "Insufficient memory to save resources.")));
3871 Do_Quit_Mwm (False);
3874 strcat (*pdata, string);
3875 *plen += strlen(string);
3876 } /* END OF FUNCTION AddStringToResourceData */
3879 /*************************************<->*************************************
3881 * DuplicateWorkspaceName (pSD, name, num)
3886 * This function searches the first "num" workspace names to see if the
3887 * passed "name" duplicates any workspace name defined so far.
3892 * pSD = pointer to screen data
3893 * name = potential string name for workspace
3894 * num = number of workspaces to check against
3898 * Return = True if a dupicate was found
3903 *************************************<->***********************************/
3905 DuplicateWorkspaceName (WmScreenData *pSD, unsigned char *name, int num)
3908 Boolean duplicate = False;
3910 if (pSD && pSD->pWS)
3912 for (i = 0; (i < num) && !duplicate; i++)
3914 if (!strcmp (pSD->pWS[i].name, (char *)name))
3925 int PrintWorkspaceList (pSD)
3929 WmWorkspaceData *pWS;
3931 ClientData *pClients[500];
3935 fprintf (stderr, "Screen: %d\n", pSD->screen);
3937 for (i =0; i < pSD->numWorkspaces; i++)
3941 fprintf (stderr, "\nWorkspace %s contains: \n", pWS->name);
3943 for (j = 0; j < pWS->numClients; j++)
3945 pCD = pWS->ppClients[j];
3946 fprintf (stderr, "\t%s\n", pCD->clientName);
3949 for (k = 0; k < numSaved; k++)
3951 if (pCD == pClients[k])
3960 pClients[numSaved++] = pCD;
3965 for (i = 0; i < numSaved; i++)
3968 fprintf (stderr, "\nClient %s is in: \n", pCD->clientName);
3969 for (j = 0; j < pCD->numInhabited; j++)
3971 pWS = GetWorkspaceData (pCD->pSD, pCD->pWsList[j].wsID);
3972 fprintf (stderr, "\t%s\n", pWS->name);
3976 } /* END OF FUNCTION PrintWorkspaceList */