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 librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
25 * (c) Copyright 1987,1988,1989,1990,1992,1993,1994 HEWLETT-PACKARD COMPANY
26 * (c) Copyright 1993, 1994 International Business Machines Corp.
27 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
28 * (c) Copyright 1993, 1994 Novell, Inc.
33 static char rcsid[] = "$XConsortium: WmWrkspace.c /main/7 1996/10/23 17:26:33 rswiston $"
43 #include "WmResNames.h"
44 #include <X11/Xutil.h>
53 #include "WmIPC.h" /* must be after DtP.h */
55 #include "WmPresence.h"
60 #define MIN(a,b) ((a)<=(b)?(a):(b))
64 #define MAX(a,b) ((a)>=(b)?(a):(b))
68 /* internally defined functions */
70 #include "WmWrkspace.h"
72 /******** Static Function Declarations ********/
74 static void InsureUniqueWorkspaceHints(
77 /******** End Static Function Declarations ********/
79 /* FindDtSessionMatch () put in WmResParse.h */
81 /* external functions */
82 #include "WmBackdrop.h"
84 #include "WmFunction.h"
86 #include "WmIconBox.h"
88 #include "WmProperty.h"
89 #include "WmResParse.h"
90 #include "WmWinInfo.h"
91 #include "WmWinList.h"
92 #include "WmWinState.h"
99 /* a dynamically allocated list of workspaces used
100 * by F_AddToAllWorkspaces
102 static int numResIDs = 0;
103 static WorkspaceID *pResIDs = NULL;
107 /*************************************<->*************************************
109 * ChangeToWorkspace (pNewWS)
114 * This function changes to a new workspace.
118 * pNewWS = pointer to workspace data
121 *************************************<->***********************************/
125 WmWorkspaceData *pNewWS )
130 WmScreenData *pSD = pNewWS->pSD;
133 Context wsContext = F_CONTEXT_NONE;
135 if (pNewWS == pSD->pActiveWS)
136 return; /* already there */
138 pSD->pLastWS = pSD->pActiveWS;
141 * Go through client list of old workspace and hide windows
142 * that shouldn't appear in new workspace.
145 if (pSD->presence.shellW &&
146 pSD->presence.onScreen &&
147 pSD->presence.contextForClient == F_CONTEXT_ICON)
149 pWsPCD = pSD->presence.pCDforClient;
150 wsContext = pSD->presence.contextForClient;
151 HidePresenceBox (pSD, False);
154 for (i = 0; i < pSD->pActiveWS->numClients; i++)
156 pCD = pSD->pActiveWS->ppClients[i];
157 if (!ClientInWorkspace (pNewWS, pCD))
159 SetClientWsIndex(pCD);
160 SetClientState (pCD, pCD->clientState | UNSEEN_STATE,
166 * Hide active icon text label
168 if ((pSD->iconDecoration & ICON_ACTIVE_LABEL_PART) &&
169 wmGD.activeIconTextDisplayed)
171 HideActiveIconText(pSD);
179 UnmapIconBoxes (pSD->pLastWS);
183 * Set new active workspace
185 pSD->pActiveWS = pNewWS;
186 ChangeBackdrop (pNewWS);
189 * Go through client list of new workspace and show windows
190 * that should appear.
192 for (i = 0; i < pNewWS->numClients; i++)
194 pCD = pNewWS->ppClients[i];
195 SetClientWsIndex(pCD);
196 if (pCD->clientState & UNSEEN_STATE)
199 (pCD->clientState & ~UNSEEN_STATE), CurrentTime);
201 if ((pCD->clientState == MINIMIZED_STATE) &&
202 ((!pCD->pSD->useIconBox) ||
205 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
206 ICON_X(pCD), ICON_Y(pCD));
211 unsigned int xOffset, yOffset;
214 * Adjust for icons in the box
217 if (pNewWS->pIconBox)
219 xOffset = IB_MARGIN_WIDTH;
220 yOffset = IB_MARGIN_HEIGHT;
229 * reparent icon window to frame in this workspace
231 if ((ICON_DECORATION(pCD) & ICON_IMAGE_PART) &&
234 ReparentIconWindow (pCD, xOffset, yOffset);
239 if ( (wsContext == F_CONTEXT_ICON &&
240 ClientInWorkspace (ACTIVE_WS, pWsPCD)) ||
242 (pSD->presence.shellW &&
243 ! pSD->presence.userDismissed &&
244 ClientInWorkspace (ACTIVE_WS, pSD->presence.pCDforClient) &&
245 pSD->presence.contextForClient == F_CONTEXT_ICON))
247 ShowPresenceBox(pSD->presence.pCDforClient, F_CONTEXT_ICON);
251 /* sync up workspace info property with current state */
252 UpdateWorkspaceInfoProperty (pSD);
254 SetCurrentWorkspaceProperty (pSD);
256 /* send workspace change broadcast message */
257 dtSendWorkspaceModifyNotification(pSD, (Atom) pNewWS->id,
258 DtWSM_REASON_CURRENT);
260 } /* END OF FUNCTION ChangeToWorkspace */
264 /******************************<->*************************************
266 * ChangeWorkspaceTitle (pWS, pchTitle)
270 * Set the title for a workspace.
274 * pWS = pointer to workspace data
275 * pchTitle = new title to assign to this workspace
284 ******************************<->***********************************/
287 ChangeWorkspaceTitle(
288 WmWorkspaceData *pWS,
294 * Convert string to XmString
296 xmstr = XmStringCreateLocalized (pchTitle);
303 * Replace title in workspace data
305 XmStringFree (pWS->title);
309 * Save changes to resource database
311 SaveWorkspaceResources (pWS, (WM_RES_WORKSPACE_TITLE));
314 * Replace old workspace in info property
316 SetWorkspaceInfoProperty (pWS);
318 UpdateWorkspaceInfoProperty (pWS->pSD);
323 * Inform the world of the new workspace title
325 dtSendWorkspaceModifyNotification(pWS->pSD, pWS->id, DtWSM_REASON_TITLE);
327 } /* END OF FUNCTION ChangeWorkspaceTitle */
328 #endif /* PANELIST */
331 /*************************************<->*************************************
333 * UpdateWorkspacePresenceProperty (pCD)
338 * This function updates the _DT_WORKSPACE_PRESENCE property for a
343 * pCD = pointer to client data
346 *************************************<->***********************************/
349 UpdateWorkspacePresenceProperty(
353 static Atom *pPresence = NULL;
354 static unsigned long cPresence = 0;
357 if (wmGD.useStandardBehavior)
360 * Don't change any workspace properties in standard behavior
368 /* allocate initial list */
369 if (!(pPresence = (Atom *)
370 XtMalloc (pCD->pSD->numWorkspaces * sizeof(Atom))))
372 Warning (((char *)GETMESSAGE(76, 1, "Insufficient memory for workspace presence property")));
376 cPresence = pCD->pSD->numWorkspaces;
380 if (cPresence < pCD->numInhabited)
382 /* allocate bigger list */
383 if (!(pPresence = (Atom *)
384 XtRealloc ((char *)pPresence, pCD->numInhabited * sizeof(Atom))))
386 Warning (((char *)GETMESSAGE(76, 2, "Insufficient memory for workspace presence property")));
390 cPresence = pCD->numInhabited;
394 for (i = 0; (i < pCD->numInhabited) && (i < cPresence) ; i++)
396 pPresence[i] = pCD->pWsList[i].wsID;
399 SetWorkspacePresence (pCD->client, pPresence,
400 MIN(pCD->numInhabited, cPresence));
402 } /* END OF FUNCTION UpdateWorkspacePresenceProperty */
406 /*************************************<->*************************************
408 * UpdateWorkspaceInfoProperty (pSD)
413 * This function updates the _DT_WORKSPACE_INFO property for the
418 * pSD = pointer to screen data
421 *************************************<->***********************************/
424 UpdateWorkspaceInfoProperty(
428 WorkspaceInfo *pWsInfo;
429 WmWorkspaceData *pws;
432 if (wmGD.useStandardBehavior)
435 * Don't change any workspace properties in standard behavior
441 if (pWsInfo = (WorkspaceInfo *)
442 XtMalloc (pSD->numWorkspaces * sizeof(WorkspaceInfo)))
444 /* put current workspace at top of list */
445 pWsInfo[0].workspace = pSD->pActiveWS->id;
446 pWsInfo[0].backgroundWindow = pSD->pActiveWS->backdrop.window;
447 pWsInfo[0].bg = pSD->pActiveWS->backdrop.background;
448 pWsInfo[0].fg = pSD->pActiveWS->backdrop.foreground;
449 pWsInfo[0].backdropName = pSD->pActiveWS->backdrop.nameAtom;
451 /* add in the rest of the workspaces */
453 for (count = 1; count < pSD->numWorkspaces; count++)
455 if (pWsInfo[0].workspace == pws->id)
456 pws++; /* already at top, skip this one */
458 pWsInfo[count].workspace = pws->id;
459 pWsInfo[count].backgroundWindow = pws->backdrop.window;
460 pWsInfo[count].bg = pws->backdrop.background;
461 pWsInfo[count].fg = pws->backdrop.foreground;
462 pWsInfo[count].backdropName = pws->backdrop.nameAtom;
466 /* set the property */
467 SetWorkspaceInfo (pSD->wmWorkspaceWin, pWsInfo,
470 XtFree ((char *)pWsInfo);
474 Warning (((char *)GETMESSAGE(76, 3, "Insufficient memory to update workspace info")));
477 } /* END OF FUNCTION UpdateWorkspaceInfoProperty */
481 /*************************************<->*************************************
483 * AddPersistentWindow (pWS)
488 * This function adds windows that want to be in all workspaces to
489 * the workspace passed in.
493 * pWS = pointer to workspace data
498 *************************************<->***********************************/
501 AddPersistentWindows(
502 WmWorkspaceData *pWS)
505 WmScreenData *pSD = pWS->pSD;
507 ClientListEntry *pCLE;
510 * For all the windows managed for this screen, see if they
511 * want to be in all workspaces and add them to this workspace.
513 pCLE = pSD->clientList;
518 * Process all the non-icon client list entries
520 if ((pCLE->type == NORMAL_STATE) &&
521 (pCLE->pCD->putInAll))
523 AddClientToWorkspaces( pCLE->pCD, &(pWS->id), 1 );
527 * Test for exit condition and advance client list pointer
529 if (pCLE == pSD->lastClient)
532 pCLE = pCLE->nextSibling;
535 } /* END OF FUNCTION AddPersistentWindows */
538 /*************************************<->*************************************
540 * CreateWorkspace (pSD, pchTitle)
545 * This function creates a new workspace.
549 * pSD = pointer to screen data
550 * pchTitle = user-visible title for the workspace (may be NULL)
554 * Returns pointer to workspace data if successful.
556 *************************************<->***********************************/
561 unsigned char *pchTitle )
564 WmWorkspaceData *pWS = NULL;
569 * Allocate more workspace datas if we have no spares
571 if (pSD->numWsDataAllocated <= pSD->numWorkspaces)
573 iActiveWS = (pSD->pActiveWS - pSD->pWS) / sizeof (WmWorkspaceData);
574 pSD->numWsDataAllocated += WS_ALLOC_AMOUNT;
575 pSD->pWS = (WmWorkspaceData *) XtRealloc ((char *)pSD->pWS,
576 pSD->numWsDataAllocated * sizeof(WmWorkspaceData));
577 pSD->pActiveWS = &(pSD->pWS[iActiveWS]);
581 * Give this workspace a name
583 pWS = &pSD->pWS[pSD->numWorkspaces];
584 string = (String) GenerateWorkspaceName (pSD, pSD->numWorkspaces);
585 pWS->name = XtNewString (string);
588 * Initialize the workspace data structure
590 InitWmWorkspace (pWS, pSD);
594 XmStringFree (pWS->title);
595 pWS->title = XmStringCreateLocalized ((char *)pchTitle);
599 * bump workspace count
601 pSD->numWorkspaces++;
604 * update the properties that announce workspace info
606 SetWorkspaceInfoProperty (pWS);
607 SetWorkspaceListProperty (pSD);
609 SaveWorkspaceResources(pWS, (WM_RES_WORKSPACE_LIST |
610 WM_RES_WORKSPACE_COUNT |
611 WM_RES_WORKSPACE_TITLE));
612 dtSendWorkspaceModifyNotification(pSD, pWS->id, DtWSM_REASON_ADD);
615 * Insure there's an iconbox for this workspace
619 AddIconBoxForWorkspace (pWS);
623 * Add windows to this workspaces that want to be in "all"
626 AddPersistentWindows (pWS);
629 * Update workspace presence dialog data
631 UpdatePresenceWorkspaces(pSD);
634 } /* END OF FUNCTION CreateWorkspace */
637 /*************************************<->*************************************
639 * DeleteWorkspace (pWS)
644 * This function deletes a workspace.
648 * pWS = pointer to screen data
652 * Returns pointer to workspace data if successful.
654 *************************************<->***********************************/
658 WmWorkspaceData *pWS )
661 WmWorkspaceData *pWSdest; /* destination WS */
664 WmScreenData *pSD = pWS->pSD;
667 if (pSD->numWorkspaces > 1)
670 * Find index for "next" workspace
672 for (iNextWs = 0; iNextWs < pSD->numWorkspaces; iNextWs++)
674 if (pSD->pWS[iNextWs].id == pWS->id)
681 /* check bounds and wrap */
682 if (iNextWs >= pSD->numWorkspaces)
686 * Determine default destination for clients that exist
687 * only in the workspace being deleted.
689 if (pWS == ACTIVE_WS)
691 pWSdest = &(pSD->pWS[iNextWs]);
696 * Use the "current" workspace as the default destination
702 * Move all clients out of this workspace
704 while (pWS->numClients > 0)
706 /* repeatedly remove the first one until all are gone */
707 pCD = pWS->ppClients[0];
710 if (pCD->numInhabited == 1)
712 if (!(pCD->clientFlags & (ICON_BOX)))
714 AddClientToWorkspaces (pCD, &(pWSdest->id), 1);
718 RemoveClientFromWorkspaces (pCD, &(pWS->id), 1);
722 * If we're deleting the current workspace,
723 * then change to another workspace.
725 if (pWS == ACTIVE_WS)
727 ChangeToWorkspace (pWSdest);
731 * Save the workspace ID for the notification message.
736 * Destroy the icon box for the workspace if one was used
740 DestroyIconBox (pWS);
744 * Delete the property containing information on this workspace
746 DeleteWorkspaceInfoProperty (pWS);
749 * Delete the workspace data structures
751 if (pWS->backdrop.imagePixmap)
753 if (!XmDestroyPixmap (XtScreen(pWS->workspaceTopLevelW),
754 pWS->backdrop.imagePixmap))
756 /* not in Xm pixmap cache */
760 /* free pWS->backdrop.image */
761 if ((pWS->backdrop.flags & BACKDROP_IMAGE_ALLOCED) &&
762 (pWS->backdrop.image))
764 free (pWS->backdrop.image);
768 * Free up icon placement data
770 if (wmGD.iconAutoPlace)
772 if (pWS->IPData.placeList != NULL)
773 XtFree ((char *) pWS->IPData.placeList);
774 if (pWS->IPData.placementRowY != NULL)
775 XtFree ((char *) pWS->IPData.placementRowY);
776 if (pWS->IPData.placementColX != NULL)
777 XtFree ((char *) pWS->IPData.placementColX);
780 XtFree ((char *) pWS->name);
781 XmStringFree (pWS->title);
782 XtFree ((char *) pWS->ppClients);
783 if (pWS->iconBoxGeometry) XtFree ((char *) pWS->iconBoxGeometry);
784 XtDestroyWidget (pWS->workspaceTopLevelW);
787 * Compress the list of workspaces if we're not deleting
788 * the last one. (Do piece-wise to avoid overlapping copy
793 WmWorkspaceData *pWSdest;
794 WmWorkspaceData *pWSsrc;
798 pWSsrc = &(pSD->pWS[iNextWs]);
800 for (j=iNextWs; j < pSD->numWorkspaces; j++)
802 memcpy (pWSdest, pWSsrc, sizeof(WmWorkspaceData));
803 if (pSD->pActiveWS == pWSsrc)
805 pSD->pActiveWS = pWSdest;
813 * We now have one less workspace.
815 pSD->numWorkspaces--;
818 * Update the properties that announce workspace info.
820 SetWorkspaceListProperty (pSD);
822 SaveWorkspaceResources(pWSdest,
823 (WM_RES_WORKSPACE_LIST | WM_RES_WORKSPACE_COUNT));
825 dtSendWorkspaceModifyNotification(pSD, aOldId, DtWSM_REASON_DELETE);
828 * Update workspace presence dialog data
830 UpdatePresenceWorkspaces(pSD);
832 } /* END OF FUNCTION DeleteWorkspace */
835 /*************************************<->*************************************
837 * ProcessDtWmHints (pCD)
842 * Process the _DT_WM_HINTS property on the window (if any).
847 * pCD = pointer to client data
852 * pCD = may be changed.
854 *************************************<->***********************************/
857 ProcessDtWmHints (ClientData *pCD)
866 #endif /* PANELIST */
869 * Retrieve the _DT_WM_HINTS property if it exists.
872 property = XmInternAtom(DISPLAY, _XA_DT_WM_HINTS, False);
874 propertyVUE = XmInternAtom(DISPLAY, _XA_VUE_WM_HINTS, False);
879 ((HasProperty (pCD, property)) || (HasProperty (pCD, propertyVUE)))
881 (HasProperty (pCD, property))
883 && (_DtWsmGetDtWmHints (DISPLAY, pCD->client, &pHints) == Success))
885 pCD->clientFlags |= GOT_DT_WM_HINTS;
886 if (pHints->flags & DtWM_HINTS_FUNCTIONS)
888 if (pHints->functions & DtWM_FUNCTION_ALL)
890 /* client indicating inapplicable functions */
891 pCD->dtwmFunctions &= ~(pHints->functions);
895 /* client indicating applicable functions */
896 pCD->dtwmFunctions &= pHints->functions;
900 if (pHints->flags & DtWM_HINTS_BEHAVIORS)
902 /* set applicable behaviors */
903 pCD->dtwmBehaviors = pHints->behaviors;
904 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
907 * if this is a restored subpanel, remove the
908 * DtWM_BEHAVIOR_SUB_RESTORED bit so the next
909 * time through the subpanel will behave as an
912 pHints->behaviors &= ~DtWM_BEHAVIOR_SUB_RESTORED;
913 _DtWsmSetDtWmHints (DISPLAY, pCD->client, pHints);
917 XFree ((char*)pHints);
921 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_PANEL)
923 /* put it in all workspaces */
924 saveFunctions = pCD->dtwmFunctions;
925 pCD->dtwmFunctions |= DtWM_FUNCTION_OCCUPY_WS;
927 F_AddToAllWorkspaces (NULL, pCD, NULL);
929 pCD->dtwmFunctions = saveFunctions;
930 pCD->clientFlags |= FRONT_PANEL_BOX ;
932 #endif /* PANELIST */
933 } /* END OF ProcessDtWmHints */
936 /*************************************<->*************************************
938 * GetClientWorkspaceInfo (pCD, manageFlags);
943 * This function sets up the portion of client data that has to
948 * pCD = pointer to client data (only partly initialized!!)
949 * manageFlags = tells us, in particular, if we're restarting.
953 * pCD = updated client data
955 *************************************<->***********************************/
958 GetClientWorkspaceInfo(
965 unsigned int numIDs = 0;
969 * Allocate initial workspace ID list
972 if ((pCD->pWsList = (WsClientData *)
973 XtMalloc(pCD->pSD->numWorkspaces * sizeof(WsClientData))) == NULL)
975 Warning (((char *)GETMESSAGE(76, 4, "Insufficient memory for client data")));
979 pCD->pWorkspaceHints = NULL;
980 pCD->sizeWsList = pCD->pSD->numWorkspaces;
981 pCD->numInhabited = 0; /* no valid ones yet */
982 for (i = 0; i < pCD->pSD->numWorkspaces; i++)
984 pCD->pWsList[i].wsID = NULL;
985 pCD->pWsList[i].iconPlace = NO_ICON_PLACE;
986 pCD->pWsList[i].iconX = 0;
987 pCD->pWsList[i].iconY = 0;
988 pCD->pWsList[i].iconFrameWin = NULL;
989 pCD->pWsList[i].pIconBox = NULL;
991 pCD->putInAll = bAll = False;
994 * Determine initial workspace set.
996 * If this is a secondary window, use the hints from the
997 * transient tree leader.
999 * Else if we're restarting, then use our own workspace presence.
1001 * Else if a command line option is specified, use that.
1003 * Else, if workspace hints are on the window, then use them.
1005 * If none of the above work out, the window will be put into
1006 * the current workspace.
1009 ((pCD->transientLeader && GetLeaderPresence(pCD, &pIDs, &numIDs)) ||
1010 ((manageFlags & MANAGEW_WM_RESTART) &&
1011 GetMyOwnPresence (pCD, &pIDs, &numIDs)) ||
1012 (WorkspaceIsInCommand (DISPLAY, pCD, &pIDs, &numIDs)) ||
1015 (HasProperty (pCD, wmGD.xa_DT_WORKSPACE_HINTS) ||
1017 XmInternAtom (DISPLAY, _XA_VUE_WORKSPACE_HINTS,
1020 HasProperty (pCD, wmGD.xa_DT_WORKSPACE_HINTS)
1022 && (GetWorkspaceHints (DISPLAY, pCD->client, &pIDs, &numIDs, &bAll) ==
1027 * Got some workspace hints!
1029 pCD->putInAll = bAll;
1030 ProcessWorkspaceHintList (pCD, pIDs, numIDs);
1033 if (pCD->numInhabited == 0)
1036 * If not in any workspaces, then put the client into
1039 PutClientIntoWorkspace (pCD->pSD->pActiveWS, pCD);
1044 } /* END OF FUNCTION GetClientWorkspaceInfo */
1047 /*************************************<->*************************************
1049 * WorkspaceIsInCommand (dpy, pCD, ppIDs, pNumIDs)
1054 * Determine if workspace specification is in command line for client
1059 * dpy - pointer to display structure
1060 * pCD - ptr to client data
1061 * ppIDs - pointer for returning list of IDs
1062 * pNumIDs - number of IDs being returned
1066 * ppIDs - returned list of IDs
1067 * pNumIDs - number of IDs being returned
1069 * Return - True if workspace option found, false otherwise
1074 * Malloc's memory that must be freed
1076 *************************************<->***********************************/
1079 WorkspaceIsInCommand(
1082 WorkspaceID **ppIDs,
1083 unsigned int *pNumIDs )
1086 char **wmcArgv = NULL;
1087 Boolean rval = False;
1088 unsigned char *pch = NULL;
1089 XTextProperty clientMachineProp;
1091 if (FindClientDBMatch(pCD, (char **)&pch))
1095 if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
1099 XtFree((char *)pch);
1102 else if (HasProperty (pCD, XA_WM_COMMAND) &&
1103 XGetCommand (dpy, pCD->client, &wmcArgv, &wmcArgc) &&
1106 if (pCD->pSD->remainingSessionItems)
1108 if(!(XGetWMClientMachine(dpy, pCD->client, &clientMachineProp)))
1110 clientMachineProp.value = NULL;
1112 if (FindDtSessionMatch(wmcArgc, wmcArgv, pCD, pCD->pSD,
1114 (char *)clientMachineProp.value))
1117 * If we found a match to a client description
1118 * in the DtSessionHints, use the information from
1119 * the Hints instead of the command line
1123 if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
1128 * free malloced memory containing workspace list
1130 XtFree ((char *)pch);
1134 if (clientMachineProp.value)
1136 XFree ((char*)clientMachineProp.value);
1140 if (!rval && FindWsNameInCommand (wmcArgc, wmcArgv, &pch))
1142 if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
1148 if (wmcArgv != NULL)
1150 XFreeStringList (wmcArgv);
1155 } /* END OF FUNCTION WorkspaceIsInCommand */
1158 /*************************************<->*************************************
1160 * ConvertNamesToIDs (pSD, pch, ppAtoms, pNumAtoms)
1165 * Takes a string containing a list of names separated by white space
1166 * and converts it to a list of workspace IDs.
1170 * pSD - pointer to screen data
1171 * pchIn - pointer to original string
1172 * ppAtoms - pointer to an atom pointer (for returning list pointer)
1173 * pNumAtoms - pointer to the number of atoms being returned.
1177 * *ppAtoms - points to a list of atoms returned.
1178 * *pNumAtoms - the number of atoms being returned.
1180 * Return - True if some Atoms are being returned
1184 * Processes local copy of string so that pch is not modified.
1186 * The list of atoms returned has been dynamically allocated.
1187 * Please XtFree() it when you're done.
1189 *************************************<->***********************************/
1194 unsigned char *pchIn,
1195 WorkspaceID **ppAtoms,
1196 unsigned int *pNumAtoms )
1199 unsigned char *pchLocal, *pch, *pchName;
1202 WorkspaceID *pLocalIDs;
1204 if ((pLocalIDs = (WorkspaceID *) XtMalloc (WS_ALLOC_AMOUNT *
1205 sizeof(WorkspaceID))) == NULL)
1207 Warning (((char *)GETMESSAGE(76, 5, "Insufficient Memory (ConvertNamesToIDs)")));
1208 ExitWM (WM_ERROR_EXIT_VALUE);
1210 numLocalIDs = WS_ALLOC_AMOUNT;
1212 if (pchIn && (pchLocal = (unsigned char *) XtMalloc(1+strlen((char *)pchIn))))
1214 strcpy ((char *)pchLocal, (char *)pchIn);
1217 while (pchName = GetSmartString (&pch))
1223 * Check workspace for workspace titles; map to
1226 xms = XmStringCreateLocalized ((char *)pchName);
1227 for (iwsx = 0; iwsx < pSD->numWorkspaces; iwsx++)
1229 if (XmStringCompare (xms, pSD->pWS[iwsx].title))
1236 if (iwsx < pSD->numWorkspaces)
1239 * Found a workspace title we've got,
1240 * use id for workspace name
1242 pLocalIDs[num] = pSD->pWS[iwsx].id;
1248 * Try for match on workspace name
1250 pLocalIDs[num] = (WorkspaceID)
1251 XInternAtom (DISPLAY, (char *)pchName, False);
1255 if (num >= numLocalIDs)
1257 /* list too small */
1258 numLocalIDs += WS_ALLOC_AMOUNT;
1259 if ((pLocalIDs = (WorkspaceID *) XtRealloc ((char *)pLocalIDs,
1260 numLocalIDs * sizeof(WorkspaceID))) == NULL)
1262 Warning (((char *)GETMESSAGE(76, 6, "Insufficient Memory (ConvertNamesToIDs)")));
1263 ExitWM (WM_ERROR_EXIT_VALUE);
1268 XtFree ((char *)pchLocal);
1271 *ppAtoms = pLocalIDs;
1275 } /* END OF FUNCTION ConvertNamesToIDs */
1278 /*************************************<->*************************************
1280 * CheckForPutInAllRequest (pCD, pIDs, numIDs)
1285 * Tests for the presence of the "all" atom in the atom list
1286 * and sets the "putInAll" flag on the client.
1290 * pCD - pointer to client data
1291 * pIDs - pointer to ID list
1292 * numIDs - number of IDs in list
1296 * pCD - putInAll member may be set
1298 *************************************<->***********************************/
1301 CheckForPutInAllRequest(
1304 unsigned int numIDs )
1309 for (i = 0; (i < numIDs) && !(pCD->putInAll); i++)
1311 if (pIDs[i] == wmGD.xa_ALL_WORKSPACES)
1313 pCD->putInAll = True;
1318 } /* END OF FUNCTION CheckForPutInAllRequest */
1321 /*************************************<->*************************************
1323 * FindWsNameInCommand (argc, argv, ppch)
1328 * Finds and returns the workspace name option in the command line
1333 * argc - argument count
1334 * argv - argument list
1335 * ppch - string pointer to return
1340 * *ppch - points to ws name (if found)
1342 * Return - True if wsname found
1347 *************************************<->***********************************/
1350 FindWsNameInCommand(
1353 unsigned char **ppch )
1357 #define XRM_OPT "-xrm"
1358 #define WSLIST "*workspaceList:"
1359 #define WSLIST_LEN 14
1362 Boolean rval = False;
1363 unsigned char *pch, *pchTmp, *pch0;
1364 unsigned char *pchRes, *pchValue;
1368 while (--argc && !rval)
1370 if (!strcmp(argv[i], XRM_OPT) && (argc > 1))
1373 * found "-xrm", now look at resource spec
1375 pch0 = (unsigned char *) strdup (argv[i+1]);
1378 Warning (((char *)GETMESSAGE(76, 7, "Insufficient memory")));
1379 ExitWM (WM_ERROR_EXIT_VALUE);
1383 /* strip off quotes ,
1384 * separate two halve of resource spec
1386 pchRes = GetSmartString (&pch);
1389 if ((*pchRes) && (*pch))
1391 /* Erase colon at end of resource name */
1393 pch = (unsigned char *) strrchr((char *)pchRes, ':');
1399 /* find beginning of last component of resource
1402 pch = (unsigned char *) strrchr ((char *)pchRes, '*');
1403 pchTmp = (unsigned char *) strrchr ((char *)pchRes, '.');
1409 if (pch && *pch && *(pch+1))
1414 /* compare resource with our resource */
1416 if ( (!strcmp ((char *)pch, WmNworkspaceList)) ||
1417 (!strcmp ((char *)pch, WmCWorkspaceList)))
1419 /* match, compute return position in
1422 *ppch = (unsigned char *)
1423 (argv[i+1] + (pchValue - pch0));
1425 XtFree ((char *)pch0);
1430 i++; /* skip next arg */
1435 XtFree ((char *)pch0);
1442 } /* END OF FUNCTION FindWsNameInCommand */
1446 /*************************************<->*************************************
1448 * PutClientIntoWorkspace (pWS, pCD)
1453 * This function updates the data for the client and workspace to
1454 * reflect the presence of the client in the workspace.
1458 * pWS = pointer to workspace data
1459 * pCD = pointer to client data
1464 *************************************<->***********************************/
1467 PutClientIntoWorkspace(
1468 WmWorkspaceData *pWS,
1472 int i = pCD->numInhabited;
1475 /* insure the client's got enough workspace data */
1476 if (pCD->sizeWsList < pCD->pSD->numWorkspaces)
1478 iAdded = pCD->pSD->numWorkspaces - pCD->sizeWsList;
1480 pCD->sizeWsList = pCD->pSD->numWorkspaces;
1481 pCD->pWsList = (WsClientData *)
1482 XtRealloc((char *)pCD->pWsList,
1483 (pCD->pSD->numWorkspaces * sizeof(WsClientData)));
1485 /* intialized new data */
1486 j = pCD->sizeWsList - 1;
1487 for (j=1; j <= iAdded; j++)
1489 k = pCD->sizeWsList - j;
1490 pCD->pWsList[k].iconPlace = NO_ICON_PLACE;
1491 pCD->pWsList[k].iconX = 0;
1492 pCD->pWsList[k].iconY = 0;
1493 pCD->pWsList[k].iconFrameWin = (Window) 0;
1494 pCD->pWsList[k].pIconBox = NULL;
1499 /* update the client's list of workspace data */
1500 pCD->pWsList[i].wsID = pWS->id;
1501 pCD->numInhabited++;
1503 if (!(pCD->clientFlags & WM_INITIALIZATION))
1506 * Make sure there's an icon
1507 * (Don't do this during initialization, the pCD not
1508 * ready for icon making yet).
1510 InsureIconForWorkspace (pWS, pCD);
1513 /* update the workspace list of clients */
1514 AddClientToWsList (pWS, pCD);
1516 } /* END OF FUNCTION PutClientIntoWorkspace */
1519 /*************************************<->*************************************
1521 * TakeClientOutOfWorkspace (pWS, pCD)
1526 * This function updates the data for the client and the workspace
1527 * to reflect the removal of the client from the workspace.
1531 * pWS = pointer to workspace data
1532 * pCD = pointer to client data
1537 *************************************<->***********************************/
1540 TakeClientOutOfWorkspace(
1541 WmWorkspaceData *pWS,
1546 Boolean Copying = False;
1549 if (pWS && pCD && ClientInWorkspace(pWS, pCD))
1554 if (!pCD->transientLeader)
1556 pWsc = GetWsClientData (pWS, pCD);
1558 if ((pCD->pSD->useIconBox) &&
1560 (pCD->clientFunctions & MWM_FUNC_MINIMIZE))
1562 DeleteIconFromBox (pWS->pIconBox, pCD);
1564 else if (wmGD.iconAutoPlace)
1567 * Free up root icon spot
1570 if ((pWsc->iconPlace != NO_ICON_PLACE) &&
1571 (pWS->IPData.placeList[pWsc->iconPlace].pCD == pCD))
1573 pWS->IPData.placeList[pWsc->iconPlace].pCD = NULL;
1574 pWsc->iconPlace = NO_ICON_PLACE;
1580 * Remove the selected workspace and copy the remaining ones
1581 * up. (Do piece-wise to avoid overlapping copy.)
1583 for (ixA = 0; ixA < pCD->numInhabited; ixA++)
1587 memcpy (&pCD->pWsList[ixA-1], &pCD->pWsList[ixA],
1588 sizeof(WsClientData));
1590 else if (pCD->pWsList[ixA].wsID == pWS->id)
1593 * This is the one we're removing, start copying here.
1600 * Decrement the number of workspaces inhabited.
1602 pCD->numInhabited--;
1604 /* update the workspaces list of clients */
1605 RemoveClientFromWsList (pWS, pCD);
1610 Warning("TakeClientOutOfWorkspace: null workspace passed in.");
1615 } /* END OF FUNCTION TakeClientOutOfWorkspace */
1618 /*************************************<->*************************************
1620 * GetWorkspaceData (pSD, wsID)
1625 * This function finds the data that is associated with a workspace ID.
1629 * pSD = pointer to screen data
1630 * wsID = workspace ID
1634 * Function returns a pointer to the workspace data if successful,
1635 * or NULL if unsuccessful.
1637 *************************************<->***********************************/
1645 WmWorkspaceData *pWS = NULL;
1648 for (i=0; i < pSD->numWorkspaces; i++)
1650 if (pSD->pWS[i].id == wsID)
1660 /* failed to find one */
1661 Warning ("Failed to find workspace data");
1667 } /* END OF FUNCTION GetWorkspaceData */
1671 /*************************************<->*************************************
1673 * GenerateWorkspaceName (pSD, wsnum)
1678 * This function generates and returns a workspace string name from
1679 * a small number passed in.
1683 * pSD = pointer to screen data
1684 * wsNum = number for workspace
1689 * returns pointer to statically allocated data. You must copy it
1690 * to your local buffer.
1694 * Name is of the form ws<n> where <n> is a number.
1696 *************************************<->***********************************/
1699 GenerateWorkspaceName(
1704 static unsigned char nameReturned[10];
1708 * Nice n-squared algorithm...
1709 * (This should be OK for small number of workspaces)
1711 for (i=0; i <= pSD->numWorkspaces; i++)
1713 /* generate a name */
1714 sprintf ((char *)nameReturned, "ws%d", i);
1715 if (!DuplicateWorkspaceName (pSD, nameReturned, wsnum))
1719 return (nameReturned);
1721 } /* END OF FUNCTION GenerateWorkspaceName */
1725 /*************************************<->*************************************
1727 * InWindowList (w, wl, num)
1732 * This function determines if a window is in a list of windows
1736 * w = window of interest
1737 * wl = list of windows
1738 * num = number of windows in wl
1743 * The function returns "True" if "w" appears in "wl"
1745 *************************************<->***********************************/
1755 Boolean rval = False;
1757 for (i = 0; (i < num) && !rval; i++)
1767 } /* END OF FUNCTION InWindowList */
1770 /*************************************<->*************************************
1772 * ClientInWorkspace (pWS, pCD)
1777 * This function determines if a client is in a workspace
1781 * pWS = pointer to workspace data
1782 * pCD = pointer to client data
1786 * The function returns "True" if client pCD is in workspace pWS
1788 *************************************<->***********************************/
1792 WmWorkspaceData *pWS,
1797 Boolean rval = False;
1799 for (i = 0; (i < pCD->numInhabited) && !rval; i++)
1801 if (pWS->id == pCD->pWsList[i].wsID)
1809 } /* END OF FUNCTION ClientInWorkspace */
1812 /*************************************<->*************************************
1814 * GetWsClientData (pWS, pCD)
1819 * This function returns a pointer to the client's specific data for
1824 * pWS = pointer to workspace data
1825 * pCD = pointer to client data
1829 * The function returns a pointer to the client's data for this
1830 * workspace. If the client isn't in the workspace, an error is
1831 * printed and the first datum in the workspace list is returned.
1833 *************************************<->***********************************/
1837 WmWorkspaceData *pWS,
1842 WsClientData *pWsc = NULL;
1844 for (i = 0; (i < pCD->numInhabited) && !pWsc; i++)
1846 if (pWS->id == pCD->pWsList[i].wsID)
1848 pWsc = &pCD->pWsList[i];
1854 pWsc = &pCD->pWsList[0];
1859 } /* END OF FUNCTION GetWsClientData */
1862 /*************************************<->*************************************
1864 * SetClientWsIndex (pCD)
1869 * This function sets the index into the client's array of workspace
1870 * specific data. This index points to the data to be used for the
1871 * currently active workspace.
1875 * pCD = pointer to client data
1879 * The function returns an index as described above. If the client is
1880 * not in the currently active workspace, then the index returned is 0.
1882 *************************************<->***********************************/
1890 WmWorkspaceData *pWS = pCD->pSD->pActiveWS;
1892 for (i = 0; (i < pCD->numInhabited); i++)
1894 if (pWS->id == pCD->pWsList[i].wsID)
1900 if (i >= pCD->numInhabited)
1905 pCD->currentWsc = i;
1907 } /* END OF FUNCTION SetClientWsIndex */
1911 /*************************************<->*************************************
1913 * ProcessWmWorkspaceHints (pCD)
1918 * This function processes a change to the _DT_WORKSPACE_HINTS property
1919 * on a window that we manage.
1923 * pCD = pointer to client data
1927 * Returns False if we ran out of memory or no hints.
1928 * Returns True on success.
1930 *************************************<->***********************************/
1933 ProcessWorkspaceHints(
1939 unsigned int numIDs;
1940 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
1941 Boolean rval = False;
1945 WorkspaceID *pDiff = NULL;
1948 numOld = pCD->numInhabited;
1949 ReserveIdListSpace (numOld);
1950 for (i = 0; i < numOld; i++)
1952 pResIDs[i] = pCD->pWsList[i].wsID;
1955 if ((pCD->client) &&
1956 (GetWorkspaceHints (DISPLAY, pCD->client,
1957 &pIDs, &numIDs, &bAll) == Success) &&
1958 (bAll || (numIDs && (pDiff = (WorkspaceID *)
1959 XtMalloc (sizeof(WorkspaceID) * MAX(numIDs, numOld))))))
1962 * Process request to put window in all workspaces
1964 pCD->putInAll = bAll;
1965 CheckForPutInAllRequest (pCD, pIDs, numIDs);
1970 * Compute the ids to be removed.
1974 for (i=0; i < numOld; i++)
1977 for (j=0; j < numIDs; j++)
1979 if (pIDs[j] == pResIDs[i])
1988 pDiff[numDiff++] = pResIDs[i];
1993 * Remove the client from the set of workspaces
1997 RemoveClientFromWorkspaces (pCD, pDiff, numDiff);
2002 * Process request to put window in all workspaces
2007 for (i=0; i<pCD->pSD->numWorkspaces; i++)
2009 if (!ClientInWorkspace(&pCD->pSD->pWS[i], pCD))
2011 AddClientToWorkspaces (pCD, &pCD->pSD->pWS[i].id, 1);
2018 * Compute the ids to be added.
2022 for (i=0; i < numIDs; i++)
2025 for (j=0; j < numOld; j++)
2027 if (pResIDs[j] == pIDs[i])
2036 pDiff[numDiff++] = pIDs[i];
2041 * Add the client to the set of workspaces
2045 AddClientToWorkspaces (pCD, pDiff, numDiff);
2050 * If the client is not in any workspaces, then
2051 * put it in the current one
2053 * !!! Is this right? !!!
2055 if (pCD->numInhabited == 0)
2057 AddClientToWorkspaces (pCD, &pSD->pActiveWS->id, 1);
2061 * Free up the old list of hints
2063 if (pCD->pWorkspaceHints)
2065 XFree ((char *)pCD->pWorkspaceHints);
2069 XtFree ((char *)pDiff);
2073 * Save the new hints
2075 pCD->pWorkspaceHints = pIDs;
2076 pCD->numWorkspaceHints = numIDs;
2079 * Update the presence property
2081 UpdateWorkspacePresenceProperty (pCD);
2087 } /* END OF FUNCTION ProcessWorkspaceHints */
2090 /*************************************<->*************************************
2092 * InsureUniqueWorkspaceHints (pCD)
2097 * This function processes the workspace hints and removes duplicates.
2101 * pCD = pointer to client data
2105 * May modify *pWorkspaceHints and numWorkspaceHints
2107 *************************************<->***********************************/
2110 InsureUniqueWorkspaceHints(
2119 if (pCD->numWorkspaceHints < 2) return;
2121 pID = pCD->pWorkspaceHints;
2126 while (next < pCD->numWorkspaceHints)
2129 for (i = 0; i < next; i++)
2131 if (pID [next] == pID [i])
2133 /* duplicate found! */
2141 /* skip duplicates */
2146 /* not a duplicate */
2151 * We need to copy up over an old duplicate
2153 pID [trail] = pID [next];
2159 pCD->numWorkspaceHints = trail+1;
2161 } /* END OF FUNCTION InsureUniqueWorkspaceHints */
2165 /*************************************<->*************************************
2167 * ProcessWorkspaceHintList (pCD, pIDs, numIDs)
2172 * This function processes a list of workspace hints for a client.
2176 * pCD = pointer to client data
2177 * pIDs = pointer to a list of workspace IDs
2178 * numIDs = number of IDs in the list
2183 *************************************<->***********************************/
2186 ProcessWorkspaceHintList(
2189 unsigned int numIDs )
2193 WmWorkspaceData *pWS;
2199 * Keep these hints; make sure there are no duplicate
2200 * workspace requests.
2202 pCD->pWorkspaceHints = pIDs;
2203 pCD->numWorkspaceHints = numIDs;
2204 InsureUniqueWorkspaceHints (pCD);
2205 numIDs = pCD->numWorkspaceHints;
2207 if (pCD->pWorkspaceHints)
2210 * Process request to put window in all workspaces
2212 CheckForPutInAllRequest (pCD, pIDs, numIDs);
2216 for (i=0; i<pCD->pSD->numWorkspaces; i++)
2218 PutClientIntoWorkspace (&pCD->pSD->pWS[i], pCD);
2223 for (i=0; i<numIDs; i++)
2226 * Put the client into requested workspaces that
2229 if (pWS = GetWorkspaceData (pCD->pSD,
2230 pCD->pWorkspaceHints[i]))
2232 PutClientIntoWorkspace (pWS, pCD);
2239 } /* END OF FUNCTION ProcessWorkspaceHintList */
2242 /*************************************<->*************************************
2244 * RemoveSingleClientFromWorkspaces (pCD, pIDs, numIDs)
2249 * This function removes a single client from a list of workspaces
2253 * pCD = pointer to client data
2254 * pIDs = pointer to a list of workspace IDs
2255 * numIDs = number of workspace IDs
2260 *************************************<->***********************************/
2263 RemoveSingleClientFromWorkspaces(
2266 unsigned int numIDs )
2270 WmWorkspaceData *pWS;
2272 for (i=0; i < numIDs; i++)
2275 * Remove the client from the specified workspaces
2277 if ((pWS = GetWorkspaceData (pCD->pSD, pIDs[i])) &&
2278 (ClientInWorkspace (pWS, pCD)))
2281 * If this workspace is active, then make the
2282 * window unseen. We only need to call
2283 * SetClientState on the main window, the
2284 * transients will get taken care of in there.
2286 if ((pWS == pCD->pSD->pActiveWS) &&
2287 (pCD->transientLeader == NULL) &&
2288 !(pCD->clientState & UNSEEN_STATE))
2290 SetClientState (pCD,
2291 (pCD->clientState | UNSEEN_STATE), CurrentTime);
2293 TakeClientOutOfWorkspace (pWS, pCD);
2296 * Update the presence property
2298 UpdateWorkspacePresenceProperty (pCD);
2302 } /* END OF FUNCTION RemoveSingleClientFromWorkspaces */
2304 /*************************************<->*************************************
2306 * RemoveSubtreeFromWorkspaces (pCD, pIDs, numIDs)
2311 * This function removes a transient subtree from a list of workspaces
2315 * pCD = pointer to client data
2316 * pIDs = pointer to a list of workspace IDs
2317 * numIDs = number of workspace IDs
2322 *************************************<->***********************************/
2325 RemoveSubtreeFromWorkspaces(
2328 unsigned int numIDs )
2333 pNext = pCD->transientChildren;
2336 /* process all children first */
2337 if (pNext->transientChildren)
2339 RemoveSubtreeFromWorkspaces (pNext, pIDs, numIDs);
2343 RemoveSingleClientFromWorkspaces (pNext, pIDs, numIDs);
2345 pNext = pNext->transientSiblings;
2348 /* process the primary window */
2349 RemoveSingleClientFromWorkspaces (pCD, pIDs, numIDs);
2352 } /* END OF FUNCTION RemoveSubtreeFromWorkspaces */
2357 /******************************<->*************************************
2359 * pIDs = GetListOfOccupiedWorkspaces (pCD, numIDs)
2364 * This function creates a list of occupied workspaces of a particular
2365 * client, EXCLUDING the current workspace.
2369 * pCD = pointer to client data
2373 * pIDs = pointer to a list of workspace IDs
2374 * numIDs = number of workspace IDs
2378 * memory for pIDs is allocated with XtMalloc and should be
2379 * freed with XtFree.
2382 ******************************<->***********************************/
2384 GetListOfOccupiedWorkspaces(
2390 WorkspaceID *pLocalIDs = NULL;
2392 WorkspaceID activeWsID = pCD->pSD->pActiveWS->id;
2396 if ((pLocalIDs = (WorkspaceID *) XtMalloc (pCD->numInhabited *
2397 sizeof(WorkspaceID))) == NULL)
2399 Warning (((char *)GETMESSAGE(76, 7, "Insufficient memory")));
2403 for (i = 0; i < pCD->numInhabited; i++)
2405 if (activeWsID != pCD->pWsList[i].wsID)
2407 pLocalIDs[(*numIDs)++] = pCD->pWsList[i].wsID;
2413 } /* END OF FUNCTION GetListOfOccupiedWorkspaces */
2414 #endif /* PANELIST */
2417 /******************************<->*************************************
2419 * HonorAbsentMapBehavior(pCD)
2424 * This function adds a client to the current workspace and
2425 * if (pCD->absentMapBehavior == AMAP_BEHAVIOR_MOVE)
2426 * removes the client from the other workspaces
2431 * pCD = pointer to client data
2436 ******************************<->***********************************/
2439 HonorAbsentMapBehavior(
2442 int inWorkspace = 0;
2444 if (pCD->absentMapBehavior == AMAP_BEHAVIOR_MOVE)
2449 * Remove from other workspaces
2451 for (wsCnt = 0; wsCnt < pCD->numInhabited; wsCnt = inWorkspace)
2453 if (pCD->pWsList[wsCnt].wsID != pCD->pSD->pActiveWS->id)
2455 RemoveClientFromWorkspaces (pCD,
2456 &pCD->pWsList[wsCnt].wsID, 1);
2462 if (inWorkspace == 0)
2463 AddClientToWorkspaces (pCD, &ACTIVE_WS->id, 1);
2465 } /* END OF FUNCTION HonorAbsentMapBehavior */
2469 /******************************<->*************************************
2471 * RemoveClientFromWorkspaces (pCD, pIDs, numIDs)
2476 * This function removes a client from a list of workspaces
2480 * pCD = pointer to client data
2481 * pIDs = pointer to a list of workspace IDs
2482 * numIDs = number of workspace IDs
2487 ******************************<->***********************************/
2490 RemoveClientFromWorkspaces(
2493 unsigned int numIDs )
2496 ClientData *pcdLeader;
2498 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
2500 RemoveSubtreeFromWorkspaces (pcdLeader, pIDs, numIDs);
2503 } /* END OF FUNCTION RemoveClientFromWorkspaces */
2506 /*************************************<->*************************************
2508 * AddSingleClientToWorkspaces (pCD, pIDs, numIDs)
2513 * This function adds a single client to a list of workspaces
2517 * pCD = pointer to client data
2518 * pIDs = pointer to a list of workspace IDs
2519 * numIDs = number of workspace IDs
2524 *************************************<->***********************************/
2527 AddSingleClientToWorkspaces(
2530 unsigned int numIDs )
2534 WmWorkspaceData *pWS;
2536 for (i=0; i < numIDs; i++)
2539 * Add the client to the specified workspaces if
2540 * it is not already there.
2542 if ((pWS = GetWorkspaceData (pCD->pSD, pIDs[i])) &&
2543 (!ClientInWorkspace (pWS, pCD)))
2545 PutClientIntoWorkspace (pWS, pCD);
2547 if ((pWS == PSD_FOR_CLIENT(pCD)->pActiveWS) &&
2548 (pCD->transientLeader == NULL) &&
2549 (pCD->clientState & UNSEEN_STATE))
2551 SetClientState (pCD,
2552 (pCD->clientState & ~UNSEEN_STATE), CurrentTime);
2556 * Update the presence property (only on transient leader)
2558 UpdateWorkspacePresenceProperty (pCD);
2562 } /* END OF FUNCTION AddSingleClientToWorkspace */
2565 /*************************************<->*************************************
2567 * AddSubtreeToWorkspaces (pCD, pIDs, numIDs)
2572 * This function adds a client subtree to a list of workspaces
2576 * pCD = pointer to client data (head of subtree)
2577 * pIDs = pointer to a list of workspace IDs
2578 * numIDs = number of workspace IDs
2583 *************************************<->***********************************/
2586 AddSubtreeToWorkspaces(
2589 unsigned int numIDs )
2594 pNext = pCD->transientChildren;
2597 /* process all children first */
2598 if (pNext->transientChildren)
2600 AddSubtreeToWorkspaces (pNext, pIDs, numIDs);
2604 AddSingleClientToWorkspaces (pNext, pIDs, numIDs);
2606 pNext = pNext->transientSiblings;
2609 /* process the primary window */
2610 AddSingleClientToWorkspaces (pCD, pIDs, numIDs);
2613 } /* END OF FUNCTION AddSubtreeToWorkspaces */
2616 /*************************************<->*************************************
2618 * AddClientToWorkspaces (pCD, pIDs, numIDs)
2623 * This function adds a transient tree to a list of workspaces
2627 * pCD = pointer to client data
2628 * pIDs = pointer to a list of workspace IDs
2629 * numIDs = number of workspace IDs
2634 *************************************<->***********************************/
2637 AddClientToWorkspaces(
2640 unsigned int numIDs )
2643 ClientData *pcdLeader;
2645 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
2647 AddSubtreeToWorkspaces (pcdLeader, pIDs, numIDs);
2649 } /* END OF FUNCTION AddClientToWorkspaces */
2653 /*************************************<->*************************************
2655 * AddClientToWsList (pWS, pCD)
2660 * This function adds a client to a list of clients in a workspace
2664 * pCD = pointer to client data
2665 * pWS = pointer to workspace data
2671 *************************************<->***********************************/
2675 WmWorkspaceData *pWS,
2679 if (pWS->numClients >= pWS->sizeClientList)
2681 if (pWS->sizeClientList == 0)
2683 pWS->ppClients = (ClientData **)
2684 XtMalloc (WINDOW_ALLOC_AMOUNT * sizeof(ClientData *));
2688 pWS->ppClients = (ClientData **)
2689 XtRealloc ((char *)pWS->ppClients,
2690 (pWS->sizeClientList + WINDOW_ALLOC_AMOUNT) *
2691 sizeof(ClientData *));
2694 if (!pWS->ppClients)
2696 Warning (((char *)GETMESSAGE(76, 9, "Insufficient memory to add window to workspace")));
2697 ExitWM(WM_ERROR_EXIT_VALUE);
2700 pWS->sizeClientList += WINDOW_ALLOC_AMOUNT;
2703 if (pWS->numClients < pWS->sizeClientList)
2705 pWS->ppClients[pWS->numClients] = pCD;
2708 } /* END OF FUNCTION AddClientToWsList */
2711 /*************************************<->*************************************
2713 * RemoveClientFromWsList (pWS, pCD)
2718 * This function removes a client from a list of clients in a workspace
2722 * pCD = pointer to client data
2723 * pWS = pointer to workspace data
2729 *************************************<->***********************************/
2732 RemoveClientFromWsList(
2733 WmWorkspaceData *pWS,
2739 for (dest = 0; dest < pWS->numClients; dest++)
2741 if (pWS->ppClients[dest] == pCD)
2747 for (src = dest+1; src < pWS->numClients; src++, dest++)
2749 pWS->ppClients[dest] = pWS->ppClients[src];
2754 } /* END OF FUNCTION RemoveClientFromWsList */
2757 /*************************************<->*************************************
2760 * F_CreateWorkspace (args, pCD, event)
2778 *************************************<->***********************************/
2787 WmScreenData *pSD = ACTIVE_PSD;
2789 if (pSD->numWorkspaces >= MAX_WORKSPACE_COUNT)
2791 char buffer[MAXWMPATH];
2793 * At the maximum number of allowed workspaces.
2796 ((char *)GETMESSAGE(76, 14, "Maximum number of workspaces is %d. New workspace was not created.")), MAX_WORKSPACE_COUNT);
2801 CreateWorkspace (ACTIVE_PSD, (unsigned char *)args);
2806 } /* END OF FUNCTION F_CreateWorkspace */
2809 /*************************************<->*************************************
2812 * F_DeleteWorkspace (args, pCD, event)
2830 *************************************<->***********************************/
2839 WmScreenData *pSD = ACTIVE_PSD;
2840 WmWorkspaceData *pWS = NULL;
2849 for (i=0; i<pSD->numWorkspaces; i++)
2851 if (!strcmp(pSD->pWS[i].name, args))
2853 pWS = &(pSD->pWS[i]);
2860 DeleteWorkspace (pWS);
2864 } /* END OF FUNCTION F_DeleteWorkspace */
2867 /*************************************<->*************************************
2870 * F_GotoWorkspace (args, pCD, event)
2888 *************************************<->***********************************/
2898 WmWorkspaceData *pWS;
2900 wsID = XInternAtom (DISPLAY, args, False);
2901 pWS = GetWorkspaceData (ACTIVE_PSD, wsID);
2905 ChangeToWorkspace (pWS);
2909 } /* END OF FUNCTION F_GotoWorkspace */
2914 /*************************************<->*************************************
2917 * F_AddToAllWorkspaces (args, pCD, event)
2922 * Puts a client into all workspaces
2928 * pCD = pointer to client data
2939 * The list of Ids returned has been privately allocated. Copy
2940 * if you want to save or do anything with it.
2942 *************************************<->***********************************/
2945 F_AddToAllWorkspaces(
2954 if (pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS))
2958 ReserveIdListSpace (pSD->numWorkspaces);
2960 for (i = 0; i < pSD->numWorkspaces; i++)
2962 pResIDs[i] = pSD->pWS[i].id;
2965 AddClientToWorkspaces (pCD, pResIDs, pSD->numWorkspaces);
2967 pCD->putInAll = True;
2972 } /* END OF FUNCTION F_AddToAllWorkspaces */
2975 /*************************************<->*************************************
2978 * F_Remove (args, pCD, event)
2983 * Removes a client from the current workspace
2989 * pCD = pointer to client data
3001 *************************************<->***********************************/
3010 Boolean rval = False;
3013 * Only remove if in more than one workspace.
3015 if ((pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS)) &&
3016 (pCD->numInhabited > 1))
3018 if (ClientInWorkspace (ACTIVE_WS, pCD))
3020 RemoveClientFromWorkspaces (pCD, &ACTIVE_WS->id, 1);
3021 pCD->putInAll = False;
3027 } /* END OF FUNCTION F_Remove */
3031 /*************************************<->*************************************
3033 * GetCurrentWorkspaceIndex (pSD)
3038 * Returns an index into the screens array of workspace structures
3039 * for the current workspace.
3052 *************************************<->***********************************/
3054 GetCurrentWorkspaceIndex(
3060 for (i = 0 ; i < pSD->numWorkspaces; i++)
3062 if (pSD->pWS[i].id == pSD->pActiveWS->id)
3066 if (i >= pSD->numWorkspaces)
3068 /* failed to find workspace!!! How did that happen??? */
3071 Warning ("Failed to find workspace index");
3076 } /* END OF FUNCTION GetCurrentWorkspaceIndex */
3079 /*************************************<->*************************************
3082 * InsureIconForWorkspace (pWS, pCD)
3087 * Makes sure an icon exists for the workspace
3100 *************************************<->***********************************/
3103 InsureIconForWorkspace(
3104 WmWorkspaceData *pWS,
3110 if (pCD->clientFunctions & MWM_FUNC_MINIMIZE)
3112 pWsc = GetWsClientData (pWS, pCD);
3114 if ((pCD->pSD->useIconBox) &&
3115 (!(pCD->clientFlags & (CLIENT_WM_CLIENTS | FRONT_PANEL_BOX))))
3118 * Create a new widget for the icon box
3120 if (MakeIcon (pWS, pCD))
3122 XSaveContext (DISPLAY, pWsc->iconFrameWin,
3123 wmGD.windowContextType, (caddr_t)pCD);
3125 if (pCD->iconWindow && pWsc->iconFrameWin)
3127 XGrabButton (DISPLAY, AnyButton, AnyModifier,
3128 pWsc->iconFrameWin, True,
3129 ButtonPressMask|ButtonReleaseMask|
3131 GrabModeAsync, GrabModeAsync, None,
3132 wmGD.workspaceCursor);
3135 ShowClientIconState (pCD, (pCD->clientState & ~UNSEEN_STATE));
3141 * Reuse existing icon in new workspaces. Suggest
3142 * icon position in current WS as position of icon
3145 pWsc->iconFrameWin = pCD->pWsList[0].iconFrameWin;
3146 pWsc->iconX = ICON_X(pCD);
3147 pWsc->iconY = ICON_Y(pCD);
3149 if ((pCD->clientState & ~UNSEEN_STATE) != MINIMIZED_STATE)
3151 pWsc->iconPlace = NO_ICON_PLACE;
3153 else if (!wmGD.iconAutoPlace)
3155 if (wmGD.positionIsFrame)
3157 pWsc->iconX -= pCD->clientOffset.x;
3158 pWsc->iconY -= pCD->clientOffset.y;
3160 PlaceIconOnScreen (pCD, &pWsc->iconX, &pWsc->iconY);
3162 else /* icon auto placement */
3165 CvtIconPositionToPlace (&pWS->IPData,
3166 pWsc->iconX, pWsc->iconY);
3167 if (pWS->IPData.placeList[pWsc->iconPlace].pCD)
3169 /* The spot is already occupied! Find a
3172 FindIconPlace (pCD, &pWS->IPData, pWsc->iconX,
3175 if (pWsc->iconPlace == NO_ICON_PLACE)
3177 /* Can't find a spot close by. Use the
3178 next available slot */
3179 pWsc->iconPlace = GetNextIconPlace (&pWS->IPData);
3180 if (pWsc->iconPlace == NO_ICON_PLACE)
3183 CvtIconPositionToPlace (&pWS->IPData,
3189 CvtIconPlaceToPosition (&pWS->IPData, pWsc->iconPlace,
3190 &pWsc->iconX, &pWsc->iconY);
3193 if (!(pWS->IPData.placeList[pWsc->iconPlace].pCD))
3195 pWS->IPData.placeList[pWsc->iconPlace].pCD = pCD;
3200 } /* END OF FUNCTION InsureIconForWorkspace */
3203 /*************************************<->*************************************
3206 * GetLeaderPresence (pCD, pIDs, pnumIDs)
3211 * Gets the workspace presence of the transient tree leader for a
3217 * pCD = pointer to client data
3218 * ppIDs = pointer to pointer to list of workspace ids
3219 * pnumIDs = pointer to number of workspace ids
3224 * *ppIDS = list of workspace IDs
3225 * *pnumIDs = number of workspace IDs in list
3227 * Return = true on success
3232 * ID list is dynamically allocated, please XtFree() it when you're
3235 *************************************<->***********************************/
3240 WorkspaceID **ppIDs,
3241 unsigned int *pnumIDs )
3244 ClientData *pcdLeader;
3246 Boolean rval = False;
3247 WorkspaceID *pLocalIDs;
3249 if ((pLocalIDs = (WorkspaceID *) XtMalloc (pCD->pSD->numWorkspaces *
3250 sizeof(WorkspaceID))) == NULL)
3252 Warning (((char *)GETMESSAGE(76, 10, "Insufficient Memory (GetLeaderPresence)")));
3253 ExitWM (WM_ERROR_EXIT_VALUE);
3257 * Make up list of workspaces for primary window
3259 if (pCD->transientLeader)
3261 pcdLeader = FindTransientTreeLeader (pCD);
3263 for (i = 0; i < pcdLeader->numInhabited; i++)
3265 pLocalIDs[i] = pcdLeader->pWsList[i].wsID;
3269 *pnumIDs = pcdLeader->numInhabited;
3275 } /* END OF FUNCTION GetLeaderPresence */
3278 /*************************************<->*************************************
3281 * GetMyOwnPresence (pCD, pIDs, pnumIDs)
3286 * Returns the current workspace presence for the client
3291 * pCD = pointer to client data
3292 * ppIDs = pointer to pointer to list of workspace ids
3293 * pnumIDs = pointer to number of workspace ids
3298 * *ppIDS = list of workspace IDs
3299 * *pnumIDs = number of workspace IDs in list
3301 * Return = true on success
3306 * ID list is dynamically allocated (by DtWsmGetWorkspacesOccupied).
3307 * Please XtFree() it when you're done.
3309 *************************************<->***********************************/
3314 WorkspaceID **ppIDs,
3315 unsigned int *pnumIDs )
3318 Boolean rval = False;
3319 unsigned long nIDs = (unsigned long)*pnumIDs;
3322 * Get the workspace presence property
3326 (HasProperty (pCD, wmGD.xa_DT_WORKSPACE_PRESENCE) ||
3328 XmInternAtom (DISPLAY, _XA_VUE_WORKSPACE_PRESENCE,
3331 HasProperty (pCD, wmGD.xa_DT_WORKSPACE_PRESENCE)
3333 && (DtWsmGetWorkspacesOccupied (DISPLAY, pCD->client, ppIDs,
3341 *pnumIDs = (unsigned int)nIDs;
3345 } /* END OF FUNCTION GetMyOwnPresence */
3349 /*************************************<->*************************************
3352 * ReserveIdListSpace (numIDs)
3357 * Insures that there is enough room in our privately allocated
3358 * list of workspace IDs
3363 * numIDs = number of workspace ids
3370 *************************************<->***********************************/
3379 pResIDs = (WorkspaceID *)
3380 XtMalloc (numIDs * sizeof (WorkspaceID));
3386 else if (numResIDs < numIDs)
3388 pResIDs = (WorkspaceID *) XtRealloc ((char *)pResIDs,
3389 numIDs * sizeof (WorkspaceID));
3391 numResIDs = (pResIDs)? numIDs : 0;
3394 if (pResIDs == NULL)
3396 Warning (((char *)GETMESSAGE(76, 11, "Insufficient memory")));
3397 ExitWM (WM_ERROR_EXIT_VALUE);
3400 } /* END OF FUNCTION ReserveIdListSpace */
3405 /******************************<->*************************************
3407 * SaveResources (pSD)
3411 * Saves dtwm resources to restore session
3415 * pSD = pointer to screen data
3424 *************************************<->***********************************/
3426 SaveResources( WmScreenData *pSD)
3430 WmPanelistObject pPanelist;
3431 #endif /* PANELIST */
3437 SaveWorkspaceResources(pSD->pActiveWS,
3438 (WM_RES_INITIAL_WORKSPACE |
3439 WM_RES_WORKSPACE_COUNT));
3443 pPanelist = (WmPanelistObject) pSD->wPanelist;
3444 if (pPanelist && O_Shell(pPanelist))
3446 /* This is the front panel for the screen */
3447 SaveWorkspaceResources(pSD->pActiveWS,
3448 WM_RES_FP_POSITION);
3451 /* Call the fronto panel function to save its resources */
3453 WmFrontPanelSessionSaveData();
3455 #endif /* PANELIST */
3459 for (wsCnt = 0; wsCnt < pSD->numWorkspaces; wsCnt++)
3463 SaveWorkspaceResources(&pSD->pWS[wsCnt],
3464 WM_RES_ICONBOX_GEOMETRY);
3468 SaveHelpResources(pSD);
3472 } /* END OF FUNCTION SaveResources */
3475 /******************************<->*************************************
3477 * SaveWorkspaceResource (pWS, flags)
3481 * Modifies the RESOURCE_MANAGER property to add update versions
3482 * of the requested resources.
3486 * pWS = pointer to workspace data
3495 *************************************<->***********************************/
3497 SaveWorkspaceResources(
3498 WmWorkspaceData *pWS,
3499 unsigned long flags)
3501 char *buffer = NULL;
3502 int bufferLength = 0;
3507 char screenName[1024];
3508 char tmpScreenName[10];
3512 Dimension clientWidth;
3513 Dimension clientHeight;
3516 WmPanelistObject pPanelist = (WmPanelistObject) pWS->pSD->wPanelist;
3517 ClientData *pCD_Panel ;
3518 char tmpBuffer[MAXWMPATH+1];
3519 #endif /* PANELIST */
3522 /* allocate initial data space */
3523 if ((data = (char *) XtMalloc (MAXWMPATH+1)) == NULL)
3526 GETMESSAGE(76,12,"Insufficient memory to save resources")));
3527 Do_Quit_Mwm (False);
3532 if (bufferLength == 0)
3534 buffer = (char *) XtMalloc (MAXWMPATH+1);
3535 bufferLength = MAXWMPATH;
3539 /* Get our current resource class */
3543 res_class = WM_RESOURCE_CLASS;
3547 res_class = DT_WM_RESOURCE_CLASS;
3550 strcpy(screenName, "*");
3551 strcat(screenName,XtName (pWS->pSD->screenTopLevelW));
3553 /* construct and write out the resources specification */
3555 if (flags & WM_RES_BACKDROP_IMAGE)
3557 iLen = (strlen (res_class) + strlen (screenName) +
3558 strlen (pWS->name) + strlen (WmNbackdrop) +
3559 strlen (WmNimage) + strlen (pWS->backdrop.image) + 20);
3561 if (iLen > bufferLength)
3563 bufferLength += iLen;
3565 XtRealloc (buffer, bufferLength * sizeof(char));
3568 sprintf (buffer, "%s%s*%s*%s*%s: %s\n", res_class,
3569 screenName, pWS->name,
3570 WmNbackdrop, WmNimage, pWS->backdrop.image);
3572 AddStringToResourceData (buffer, &data, &cum_len);
3576 if (flags & WM_RES_WORKSPACE_TITLE)
3580 asciiName = WmXmStringToString (pWS->title);
3582 iLen = strlen (res_class) + strlen (screenName) +
3583 strlen (pWS->name) + strlen (WmNtitle) +
3584 strlen (asciiName) + 16;
3586 if (iLen > bufferLength)
3588 bufferLength += iLen;
3590 XtRealloc (buffer, bufferLength * sizeof(char));
3593 sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
3594 screenName, pWS->name,
3595 WmNtitle, asciiName);
3597 AddStringToResourceData (buffer, &data, &cum_len);
3602 if ((flags & WM_RES_INITIAL_WORKSPACE) &&
3603 (!wmGD.useStandardBehavior))
3605 iLen = strlen (res_class) + strlen (screenName) +
3606 strlen (WmNinitialWorkspace) + strlen (pWS->name) + 14;
3608 if (iLen > bufferLength)
3610 bufferLength += iLen;
3612 XtRealloc (buffer, bufferLength * sizeof(char));
3615 sprintf (buffer, "%s%s*%s: %s\n", res_class,
3617 WmNinitialWorkspace, pWS->name);
3619 AddStringToResourceData (buffer, &data, &cum_len);
3622 if ((flags & WM_RES_WORKSPACE_LIST) &&
3623 (!wmGD.useStandardBehavior))
3625 WmWorkspaceData *pWSi;
3629 pWSi = pWS->pSD->pWS;
3631 pchQname = (char *) _DtWmParseMakeQuotedString (
3632 (unsigned char *)pWSi->name);
3633 strcpy ((char *)wmGD.tmpBuffer, pchQname);
3638 for (i=1; i<pWS->pSD->numWorkspaces; i++, pWSi++)
3640 strcat ((char *)wmGD.tmpBuffer, " ");
3641 pchQname = (char *) _DtWmParseMakeQuotedString (
3642 (unsigned char *)pWSi->name);
3643 strcat ((char *)wmGD.tmpBuffer, pchQname);
3647 sprintf (buffer, "%s%s*%s: %s\n", res_class,
3649 WmNworkspaceList, wmGD.tmpBuffer);
3651 AddStringToResourceData (buffer, &data, &cum_len);
3654 if ((flags & WM_RES_WORKSPACE_COUNT) &&
3655 (!wmGD.useStandardBehavior))
3659 sprintf (pchNumWs, "%d", pWS->pSD->numWorkspaces);
3661 iLen = strlen (res_class) + strlen (screenName) +
3662 strlen (WmNworkspaceCount) + strlen (pchNumWs) + 14;
3664 if (iLen > bufferLength)
3666 bufferLength += iLen;
3668 XtRealloc (buffer, bufferLength * sizeof(char));
3671 sprintf (buffer, "%s%s*%s: %s\n", res_class,
3673 WmNworkspaceCount, pchNumWs);
3675 AddStringToResourceData (buffer, &data, &cum_len);
3679 if ((flags & WM_RES_FP_POSITION) &&
3680 (O_Shell(pPanelist)) &&
3681 (!wmGD.useStandardBehavior) &&
3682 (!XFindContext (DISPLAY, XtWindow(O_Shell(pPanelist)),
3683 wmGD.windowContextType,
3684 (XtPointer)&pCD_Panel)))
3686 Position midX, midY, tmpX, tmpY;
3687 Dimension screenWidth, screenHeight;
3689 clientX = pCD_Panel->clientX;
3690 clientY = pCD_Panel->clientY;
3693 * Determine quadrant that the front panel midpoint is
3694 * in and save front panel with appropriate gravity.
3697 /* find panel midpoint */
3699 midX = clientX+(pCD_Panel->clientWidth >> 1);
3700 midY = clientY+(pCD_Panel->clientHeight >> 1);
3702 /* get screen dimensions */
3704 screenWidth = XDisplayWidth (DISPLAY, pCD_Panel->pSD->screen);
3705 screenHeight = XDisplayHeight (DISPLAY, pCD_Panel->pSD->screen);
3708 * Determine midpoint quadrant and set up client geometry
3709 * relative to that corner. Adjust if positionIsFrame
3712 if (midX <= (Position) screenWidth/2)
3714 if(wmGD.positionIsFrame)
3716 clientX -= pCD_Panel->frameInfo.upperBorderWidth;
3720 if (midY <= (Position) screenHeight/2)
3723 if(wmGD.positionIsFrame)
3725 clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
3726 pCD_Panel->frameInfo.titleBarHeight);
3728 sprintf (tmpBuffer, "+%d+%d\0", clientX, clientY);
3733 clientY = screenHeight - clientY - pCD_Panel->clientHeight;
3734 if(wmGD.positionIsFrame)
3736 clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
3739 sprintf (tmpBuffer, "+%d-%d\0", clientX, clientY);
3744 clientX = screenWidth - clientX - pCD_Panel->clientWidth;
3745 if (wmGD.positionIsFrame)
3747 clientX -= pCD_Panel->frameInfo.lowerBorderWidth;
3751 if (midY <= (Position) screenHeight/2)
3754 if(wmGD.positionIsFrame)
3756 clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
3757 pCD_Panel->frameInfo.titleBarHeight);
3759 sprintf (tmpBuffer, "-%d+%d\0", clientX, clientY);
3764 clientY = screenHeight - clientY - pCD_Panel->clientHeight;
3765 if(wmGD.positionIsFrame)
3767 clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
3769 sprintf (tmpBuffer, "-%d-%d\0", clientX, clientY);
3773 iLen = strlen (res_class) + strlen (screenName) +
3774 strlen (XtName(O_Shell(pPanelist))) +
3775 strlen (WmNgeometry) + strlen (tmpBuffer) + 18;
3777 if (iLen > bufferLength)
3779 bufferLength += iLen;
3781 XtRealloc (buffer, bufferLength * sizeof(char));
3784 sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
3786 XtName (O_Shell(pPanelist)),
3787 WmNgeometry, tmpBuffer);
3789 AddStringToResourceData (buffer, &data, &cum_len);
3791 #endif /* PANELIST */
3793 if ((flags & WM_RES_ICONBOX_GEOMETRY) &&
3794 (!wmGD.useStandardBehavior))
3796 /* update iconbox geometry string */
3798 if (pWS->iconBoxGeometry)
3800 XtFree((char *) (pWS->iconBoxGeometry));
3801 pWS->iconBoxGeometry = NULL;
3804 clientWidth = (pWS->pIconBox->pCD_iconBox->clientWidth -
3805 pWS->pIconBox->pCD_iconBox->baseWidth) /
3806 pWS->pIconBox->pCD_iconBox->widthInc;
3808 clientHeight = (pWS->pIconBox->pCD_iconBox->clientHeight -
3809 pWS->pIconBox->pCD_iconBox->baseHeight) /
3810 pWS->pIconBox->pCD_iconBox->heightInc ;
3812 if(wmGD.positionIsFrame)
3814 CalculateGravityOffset (pWS->pIconBox->pCD_iconBox, &xoff, &yoff);
3815 clientX = pWS->pIconBox->pCD_iconBox->clientX - xoff;
3816 clientY = pWS->pIconBox->pCD_iconBox->clientY - yoff;
3820 clientX = pWS->pIconBox->pCD_iconBox->clientX;
3821 clientY = pWS->pIconBox->pCD_iconBox->clientY;
3824 sprintf (buffer, "%dx%d+%d+%d\0", clientWidth, clientHeight,
3827 pWS->iconBoxGeometry = strdup( buffer);
3829 iLen = strlen (res_class) + strlen (screenName) +
3830 strlen (pWS->name) + strlen (WmNiconBoxGeometry) +
3831 strlen (pWS->iconBoxGeometry) + 18;
3833 if (iLen > bufferLength)
3835 bufferLength += iLen;
3837 XtRealloc (buffer, bufferLength * sizeof(char));
3840 sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
3841 screenName, pWS->name,
3842 WmNiconBoxGeometry, pWS->iconBoxGeometry);
3844 AddStringToResourceData (buffer, &data, &cum_len);
3851 * Merge in the resource(s)
3853 _DtAddToResource (DISPLAY, data);
3862 } /* END OF FUNCTION SaveWorkspaceResources */
3865 /******************************<->*************************************
3867 * AddStringToResourceData (string, pdata, plen)
3871 * Adds a string to a growing buffer of strings.
3875 * string - string to add
3876 * pdata - pointer to data pointer
3877 * plen - number of bytes used in *pdata already
3881 * *pdata - data pointer (may be changed by XtRealloc)
3882 * *plen - number of bytes used in *pdata (old value plus length
3888 *************************************<->***********************************/
3890 AddStringToResourceData(
3895 if ((*pdata = (char *) XtRealloc(*pdata, *plen+strlen(string)+1)) == NULL)
3897 Warning (((char *)GETMESSAGE(76, 13, "Insufficient memory to save resources.")));
3898 Do_Quit_Mwm (False);
3901 strcat (*pdata, string);
3902 *plen += strlen(string);
3903 } /* END OF FUNCTION AddStringToResourceData */
3906 /*************************************<->*************************************
3908 * DuplicateWorkspaceName (pSD, name, num)
3913 * This function searches the first "num" workspace names to see if the
3914 * passed "name" duplicates any workspace name defined so far.
3919 * pSD = pointer to screen data
3920 * name = potential string name for workspace
3921 * num = number of workspaces to check against
3925 * Return = True if a dupicate was found
3930 *************************************<->***********************************/
3932 DuplicateWorkspaceName (WmScreenData *pSD, unsigned char *name, int num)
3935 Boolean duplicate = False;
3937 if (pSD && pSD->pWS)
3939 for (i = 0; (i < num) && !duplicate; i++)
3941 if (!strcmp (pSD->pWS[i].name, (char *)name))
3952 int PrintWorkspaceList (pSD)
3956 WmWorkspaceData *pWS;
3958 ClientData *pClients[500];
3962 fprintf (stderr, "Screen: %d\n", pSD->screen);
3964 for (i =0; i < pSD->numWorkspaces; i++)
3968 fprintf (stderr, "\nWorkspace %s contains: \n", pWS->name);
3970 for (j = 0; j < pWS->numClients; j++)
3972 pCD = pWS->ppClients[j];
3973 fprintf (stderr, "\t%s\n", pCD->clientName);
3976 for (k = 0; k < numSaved; k++)
3978 if (pCD == pClients[k])
3987 pClients[numSaved++] = pCD;
3992 for (i = 0; i < numSaved; i++)
3995 fprintf (stderr, "\nClient %s is in: \n", pCD->clientName);
3996 for (j = 0; j < pCD->numInhabited; j++)
3998 pWS = GetWorkspaceData (pCD->pSD, pCD->pWsList[j].wsID);
3999 fprintf (stderr, "\t%s\n", pWS->name);
4003 } /* END OF FUNCTION PrintWorkspaceList */
4006 /* DO NOT ADD ANYTHING AFTER THE FOLLOWING #ENDIF !!! */