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"
46 #include <X11/Xutil.h>
49 #include <Xm/AtomMgr.h>
56 #include "WmIPC.h" /* must be after DtP.h */
58 #include "WmPresence.h"
63 #define MIN(a,b) ((a)<=(b)?(a):(b))
67 #define MAX(a,b) ((a)>=(b)?(a):(b))
71 /* internally defined functions */
73 #include "WmWrkspace.h"
75 /******** Static Function Declarations ********/
77 static void InsureUniqueWorkspaceHints(
80 /******** End Static Function Declarations ********/
82 /* FindDtSessionMatch () put in WmResParse.h */
84 /* external functions */
85 #include "WmBackdrop.h"
87 #include "WmFunction.h"
89 #include "WmIconBox.h"
91 #include "WmProperty.h"
92 #include "WmResParse.h"
93 #include "WmWinInfo.h"
94 #include "WmWinList.h"
95 #include "WmWinState.h"
102 /* a dynamically allocated list of workspaces used
103 * by F_AddToAllWorkspaces
105 static int numResIDs = 0;
106 static WorkspaceID *pResIDs = NULL;
110 /*************************************<->*************************************
112 * ChangeToWorkspace (pNewWS)
117 * This function changes to a new workspace.
121 * pNewWS = pointer to workspace data
124 *************************************<->***********************************/
128 WmWorkspaceData *pNewWS )
133 WmScreenData *pSD = pNewWS->pSD;
136 Context wsContext = F_CONTEXT_NONE;
138 if (pNewWS == pSD->pActiveWS)
139 return; /* already there */
141 pSD->pLastWS = pSD->pActiveWS;
144 * Go through client list of old workspace and hide windows
145 * that shouldn't appear in new workspace.
148 if (pSD->presence.shellW &&
149 pSD->presence.onScreen &&
150 pSD->presence.contextForClient == F_CONTEXT_ICON)
152 pWsPCD = pSD->presence.pCDforClient;
153 wsContext = pSD->presence.contextForClient;
154 HidePresenceBox (pSD, False);
157 for (i = 0; i < pSD->pActiveWS->numClients; i++)
159 pCD = pSD->pActiveWS->ppClients[i];
160 if (!ClientInWorkspace (pNewWS, pCD))
162 SetClientWsIndex(pCD);
163 SetClientState (pCD, pCD->clientState | UNSEEN_STATE,
169 * Hide active icon text label
171 if ((pSD->iconDecoration & ICON_ACTIVE_LABEL_PART) &&
172 wmGD.activeIconTextDisplayed)
174 HideActiveIconText(pSD);
182 UnmapIconBoxes (pSD->pLastWS);
186 * Set new active workspace
188 pSD->pActiveWS = pNewWS;
189 ChangeBackdrop (pNewWS);
192 * Go through client list of new workspace and show windows
193 * that should appear.
195 for (i = 0; i < pNewWS->numClients; i++)
197 pCD = pNewWS->ppClients[i];
198 SetClientWsIndex(pCD);
199 if (pCD->clientState & UNSEEN_STATE)
202 (pCD->clientState & ~UNSEEN_STATE), CurrentTime);
204 if ((pCD->clientState == MINIMIZED_STATE) &&
205 ((!pCD->pSD->useIconBox) ||
208 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
209 ICON_X(pCD), ICON_Y(pCD));
214 unsigned int xOffset, yOffset;
217 * Adjust for icons in the box
220 if (pNewWS->pIconBox)
222 xOffset = IB_MARGIN_WIDTH;
223 yOffset = IB_MARGIN_HEIGHT;
232 * reparent icon window to frame in this workspace
234 if ((ICON_DECORATION(pCD) & ICON_IMAGE_PART) &&
237 ReparentIconWindow (pCD, xOffset, yOffset);
242 if ( (wsContext == F_CONTEXT_ICON &&
243 ClientInWorkspace (ACTIVE_WS, pWsPCD)) ||
245 (pSD->presence.shellW &&
246 ! pSD->presence.userDismissed &&
247 ClientInWorkspace (ACTIVE_WS, pSD->presence.pCDforClient) &&
248 pSD->presence.contextForClient == F_CONTEXT_ICON))
250 ShowPresenceBox(pSD->presence.pCDforClient, F_CONTEXT_ICON);
254 /* sync up workspace info property with current state */
255 UpdateWorkspaceInfoProperty (pSD);
257 SetCurrentWorkspaceProperty (pSD);
259 /* send workspace change broadcast message */
260 dtSendWorkspaceModifyNotification(pSD, (Atom) pNewWS->id,
261 DtWSM_REASON_CURRENT);
263 } /* END OF FUNCTION ChangeToWorkspace */
267 /******************************<->*************************************
269 * ChangeWorkspaceTitle (pWS, pchTitle)
273 * Set the title for a workspace.
277 * pWS = pointer to workspace data
278 * pchTitle = new title to assign to this workspace
287 ******************************<->***********************************/
290 ChangeWorkspaceTitle(
291 WmWorkspaceData *pWS,
297 * Convert string to XmString
299 xmstr = XmStringCreateLocalized (pchTitle);
306 * Replace title in workspace data
308 XmStringFree (pWS->title);
312 * Save changes to resource database
314 SaveWorkspaceResources (pWS, (WM_RES_WORKSPACE_TITLE));
317 * Replace old workspace in info property
319 SetWorkspaceInfoProperty (pWS);
321 UpdateWorkspaceInfoProperty (pWS->pSD);
326 * Inform the world of the new workspace title
328 dtSendWorkspaceModifyNotification(pWS->pSD, pWS->id, DtWSM_REASON_TITLE);
330 } /* END OF FUNCTION ChangeWorkspaceTitle */
331 #endif /* PANELIST */
334 /*************************************<->*************************************
336 * UpdateWorkspacePresenceProperty (pCD)
341 * This function updates the _DT_WORKSPACE_PRESENCE property for a
346 * pCD = pointer to client data
349 *************************************<->***********************************/
352 UpdateWorkspacePresenceProperty(
356 static Atom *pPresence = NULL;
357 static unsigned long cPresence = 0;
360 if (wmGD.useStandardBehavior)
363 * Don't change any workspace properties in standard behavior
371 /* allocate initial list */
372 if (!(pPresence = (Atom *)
373 XtMalloc (pCD->pSD->numWorkspaces * sizeof(Atom))))
375 Warning (((char *)GETMESSAGE(76, 1, "Insufficient memory for workspace presence property")));
379 cPresence = pCD->pSD->numWorkspaces;
383 if (cPresence < pCD->numInhabited)
385 /* allocate bigger list */
386 if (!(pPresence = (Atom *)
387 XtRealloc ((char *)pPresence, pCD->numInhabited * sizeof(Atom))))
389 Warning (((char *)GETMESSAGE(76, 2, "Insufficient memory for workspace presence property")));
393 cPresence = pCD->numInhabited;
397 for (i = 0; (i < pCD->numInhabited) && (i < cPresence) ; i++)
399 pPresence[i] = pCD->pWsList[i].wsID;
402 SetWorkspacePresence (pCD->client, pPresence,
403 MIN(pCD->numInhabited, cPresence));
405 } /* END OF FUNCTION UpdateWorkspacePresenceProperty */
409 /*************************************<->*************************************
411 * UpdateWorkspaceInfoProperty (pSD)
416 * This function updates the _DT_WORKSPACE_INFO property for the
421 * pSD = pointer to screen data
424 *************************************<->***********************************/
427 UpdateWorkspaceInfoProperty(
431 WorkspaceInfo *pWsInfo;
432 WmWorkspaceData *pws;
435 if (wmGD.useStandardBehavior)
438 * Don't change any workspace properties in standard behavior
444 if (pWsInfo = (WorkspaceInfo *)
445 XtMalloc (pSD->numWorkspaces * sizeof(WorkspaceInfo)))
447 /* put current workspace at top of list */
448 pWsInfo[0].workspace = pSD->pActiveWS->id;
449 pWsInfo[0].backgroundWindow = pSD->pActiveWS->backdrop.window;
450 pWsInfo[0].bg = pSD->pActiveWS->backdrop.background;
451 pWsInfo[0].fg = pSD->pActiveWS->backdrop.foreground;
452 pWsInfo[0].backdropName = pSD->pActiveWS->backdrop.nameAtom;
454 /* add in the rest of the workspaces */
456 for (count = 1; count < pSD->numWorkspaces; count++)
458 if (pWsInfo[0].workspace == pws->id)
459 pws++; /* already at top, skip this one */
461 pWsInfo[count].workspace = pws->id;
462 pWsInfo[count].backgroundWindow = pws->backdrop.window;
463 pWsInfo[count].bg = pws->backdrop.background;
464 pWsInfo[count].fg = pws->backdrop.foreground;
465 pWsInfo[count].backdropName = pws->backdrop.nameAtom;
469 /* set the property */
470 SetWorkspaceInfo (pSD->wmWorkspaceWin, pWsInfo,
473 XtFree ((char *)pWsInfo);
477 Warning (((char *)GETMESSAGE(76, 3, "Insufficient memory to update workspace info")));
480 } /* END OF FUNCTION UpdateWorkspaceInfoProperty */
484 /*************************************<->*************************************
486 * AddPersistentWindow (pWS)
491 * This function adds windows that want to be in all workspaces to
492 * the workspace passed in.
496 * pWS = pointer to workspace data
501 *************************************<->***********************************/
504 AddPersistentWindows(
505 WmWorkspaceData *pWS)
508 WmScreenData *pSD = pWS->pSD;
510 ClientListEntry *pCLE;
513 * For all the windows managed for this screen, see if they
514 * want to be in all workspaces and add them to this workspace.
516 pCLE = pSD->clientList;
521 * Process all the non-icon client list entries
523 if ((pCLE->type == NORMAL_STATE) &&
524 (pCLE->pCD->putInAll))
526 AddClientToWorkspaces( pCLE->pCD, &(pWS->id), 1 );
530 * Test for exit condition and advance client list pointer
532 if (pCLE == pSD->lastClient)
535 pCLE = pCLE->nextSibling;
538 } /* END OF FUNCTION AddPersistentWindows */
541 /*************************************<->*************************************
543 * CreateWorkspace (pSD, pchTitle)
548 * This function creates a new workspace.
552 * pSD = pointer to screen data
553 * pchTitle = user-visible title for the workspace (may be NULL)
557 * Returns pointer to workspace data if successful.
559 *************************************<->***********************************/
564 unsigned char *pchTitle )
567 WmWorkspaceData *pWS = NULL;
572 * Allocate more workspace datas if we have no spares
574 if (pSD->numWsDataAllocated <= pSD->numWorkspaces)
576 iActiveWS = (pSD->pActiveWS - pSD->pWS) / sizeof (WmWorkspaceData);
577 pSD->numWsDataAllocated += WS_ALLOC_AMOUNT;
578 pSD->pWS = (WmWorkspaceData *) XtRealloc ((char *)pSD->pWS,
579 pSD->numWsDataAllocated * sizeof(WmWorkspaceData));
580 pSD->pActiveWS = &(pSD->pWS[iActiveWS]);
584 * Give this workspace a name
586 pWS = &pSD->pWS[pSD->numWorkspaces];
587 string = (String) GenerateWorkspaceName (pSD, pSD->numWorkspaces);
588 pWS->name = XtNewString (string);
591 * Initialize the workspace data structure
593 InitWmWorkspace (pWS, pSD);
597 XmStringFree (pWS->title);
598 pWS->title = XmStringCreateLocalized ((char *)pchTitle);
602 * bump workspace count
604 pSD->numWorkspaces++;
607 * update the properties that announce workspace info
609 SetWorkspaceInfoProperty (pWS);
610 SetWorkspaceListProperty (pSD);
612 SaveWorkspaceResources(pWS, (WM_RES_WORKSPACE_LIST |
613 WM_RES_WORKSPACE_COUNT |
614 WM_RES_WORKSPACE_TITLE));
615 dtSendWorkspaceModifyNotification(pSD, pWS->id, DtWSM_REASON_ADD);
618 * Insure there's an iconbox for this workspace
622 AddIconBoxForWorkspace (pWS);
626 * Add windows to this workspaces that want to be in "all"
629 AddPersistentWindows (pWS);
632 * Update workspace presence dialog data
634 UpdatePresenceWorkspaces(pSD);
637 } /* END OF FUNCTION CreateWorkspace */
640 /*************************************<->*************************************
642 * DeleteWorkspace (pWS)
647 * This function deletes a workspace.
651 * pWS = pointer to screen data
655 * Returns pointer to workspace data if successful.
657 *************************************<->***********************************/
661 WmWorkspaceData *pWS )
664 WmWorkspaceData *pWSdest; /* destination WS */
667 WmScreenData *pSD = pWS->pSD;
670 if (pSD->numWorkspaces > 1)
673 * Find index for "next" workspace
675 for (iNextWs = 0; iNextWs < pSD->numWorkspaces; iNextWs++)
677 if (pSD->pWS[iNextWs].id == pWS->id)
684 /* check bounds and wrap */
685 if (iNextWs >= pSD->numWorkspaces)
689 * Determine default destination for clients that exist
690 * only in the workspace being deleted.
692 if (pWS == ACTIVE_WS)
694 pWSdest = &(pSD->pWS[iNextWs]);
699 * Use the "current" workspace as the default destination
705 * Move all clients out of this workspace
707 while (pWS->numClients > 0)
709 /* repeatedly remove the first one until all are gone */
710 pCD = pWS->ppClients[0];
713 if (pCD->numInhabited == 1)
715 if (!(pCD->clientFlags & (ICON_BOX)))
717 AddClientToWorkspaces (pCD, &(pWSdest->id), 1);
721 RemoveClientFromWorkspaces (pCD, &(pWS->id), 1);
725 * If we're deleting the current workspace,
726 * then change to another workspace.
728 if (pWS == ACTIVE_WS)
730 ChangeToWorkspace (pWSdest);
734 * Save the workspace ID for the notification message.
739 * Destroy the icon box for the workspace if one was used
743 DestroyIconBox (pWS);
747 * Delete the property containing information on this workspace
749 DeleteWorkspaceInfoProperty (pWS);
752 * Delete the workspace data structures
754 if (pWS->backdrop.imagePixmap)
756 if (!XmDestroyPixmap (XtScreen(pWS->workspaceTopLevelW),
757 pWS->backdrop.imagePixmap))
759 /* not in Xm pixmap cache */
763 /* free pWS->backdrop.image */
764 if ((pWS->backdrop.flags & BACKDROP_IMAGE_ALLOCED) &&
765 (pWS->backdrop.image))
767 free (pWS->backdrop.image);
771 * Free up icon placement data
773 if (wmGD.iconAutoPlace)
775 if (pWS->IPData.placeList != NULL)
776 XtFree ((char *) pWS->IPData.placeList);
777 if (pWS->IPData.placementRowY != NULL)
778 XtFree ((char *) pWS->IPData.placementRowY);
779 if (pWS->IPData.placementColX != NULL)
780 XtFree ((char *) pWS->IPData.placementColX);
783 XtFree ((char *) pWS->name);
784 XmStringFree (pWS->title);
785 XtFree ((char *) pWS->ppClients);
786 if (pWS->iconBoxGeometry) XtFree ((char *) pWS->iconBoxGeometry);
787 XtDestroyWidget (pWS->workspaceTopLevelW);
790 * Compress the list of workspaces if we're not deleting
791 * the last one. (Do piece-wise to avoid overlapping copy
796 WmWorkspaceData *pWSdest;
797 WmWorkspaceData *pWSsrc;
801 pWSsrc = &(pSD->pWS[iNextWs]);
803 for (j=iNextWs; j < pSD->numWorkspaces; j++)
805 memcpy (pWSdest, pWSsrc, sizeof(WmWorkspaceData));
806 if (pSD->pActiveWS == pWSsrc)
808 pSD->pActiveWS = pWSdest;
816 * We now have one less workspace.
818 pSD->numWorkspaces--;
821 * Update the properties that announce workspace info.
823 SetWorkspaceListProperty (pSD);
825 SaveWorkspaceResources(pWSdest,
826 (WM_RES_WORKSPACE_LIST | WM_RES_WORKSPACE_COUNT));
828 dtSendWorkspaceModifyNotification(pSD, aOldId, DtWSM_REASON_DELETE);
831 * Update workspace presence dialog data
833 UpdatePresenceWorkspaces(pSD);
835 } /* END OF FUNCTION DeleteWorkspace */
838 /*************************************<->*************************************
840 * ProcessDtWmHints (pCD)
845 * Process the _DT_WM_HINTS property on the window (if any).
850 * pCD = pointer to client data
855 * pCD = may be changed.
857 *************************************<->***********************************/
860 ProcessDtWmHints (ClientData *pCD)
869 #endif /* PANELIST */
872 * Retrieve the _DT_WM_HINTS property if it exists.
875 property = XmInternAtom(DISPLAY, _XA_DT_WM_HINTS, False);
877 propertyVUE = XmInternAtom(DISPLAY, _XA_VUE_WM_HINTS, False);
882 ((HasProperty (pCD, property)) || (HasProperty (pCD, propertyVUE)))
884 (HasProperty (pCD, property))
886 && (_DtWsmGetDtWmHints (DISPLAY, pCD->client, &pHints) == Success))
888 pCD->clientFlags |= GOT_DT_WM_HINTS;
889 if (pHints->flags & DtWM_HINTS_FUNCTIONS)
891 if (pHints->functions & DtWM_FUNCTION_ALL)
893 /* client indicating inapplicable functions */
894 pCD->dtwmFunctions &= ~(pHints->functions);
898 /* client indicating applicable functions */
899 pCD->dtwmFunctions &= pHints->functions;
903 if (pHints->flags & DtWM_HINTS_BEHAVIORS)
905 /* set applicable behaviors */
906 pCD->dtwmBehaviors = pHints->behaviors;
907 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
910 * if this is a restored subpanel, remove the
911 * DtWM_BEHAVIOR_SUB_RESTORED bit so the next
912 * time through the subpanel will behave as an
915 pHints->behaviors &= ~DtWM_BEHAVIOR_SUB_RESTORED;
916 _DtWsmSetDtWmHints (DISPLAY, pCD->client, pHints);
920 XFree ((char*)pHints);
924 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_PANEL)
926 /* put it in all workspaces */
927 saveFunctions = pCD->dtwmFunctions;
928 pCD->dtwmFunctions |= DtWM_FUNCTION_OCCUPY_WS;
930 F_AddToAllWorkspaces (NULL, pCD, NULL);
932 pCD->dtwmFunctions = saveFunctions;
933 pCD->clientFlags |= FRONT_PANEL_BOX ;
935 #endif /* PANELIST */
936 } /* END OF ProcessDtWmHints */
939 /*************************************<->*************************************
941 * GetClientWorkspaceInfo (pCD, manageFlags);
946 * This function sets up the portion of client data that has to
951 * pCD = pointer to client data (only partly initialized!!)
952 * manageFlags = tells us, in particular, if we're restarting.
956 * pCD = updated client data
958 *************************************<->***********************************/
961 GetClientWorkspaceInfo(
968 unsigned int numIDs = 0;
972 * Allocate initial workspace ID list
975 if ((pCD->pWsList = (WsClientData *)
976 XtMalloc(pCD->pSD->numWorkspaces * sizeof(WsClientData))) == NULL)
978 Warning (((char *)GETMESSAGE(76, 4, "Insufficient memory for client data")));
982 pCD->pWorkspaceHints = NULL;
983 pCD->sizeWsList = pCD->pSD->numWorkspaces;
984 pCD->numInhabited = 0; /* no valid ones yet */
985 for (i = 0; i < pCD->pSD->numWorkspaces; i++)
987 pCD->pWsList[i].wsID = None;
988 pCD->pWsList[i].iconPlace = NO_ICON_PLACE;
989 pCD->pWsList[i].iconX = 0;
990 pCD->pWsList[i].iconY = 0;
991 pCD->pWsList[i].iconFrameWin = None;
992 pCD->pWsList[i].pIconBox = NULL;
994 pCD->putInAll = bAll = False;
997 * Determine initial workspace set.
999 * If this is a secondary window, use the hints from the
1000 * transient tree leader.
1002 * Else if we're restarting, then use our own workspace presence.
1004 * Else if a command line option is specified, use that.
1006 * Else, if workspace hints are on the window, then use them.
1008 * If none of the above work out, the window will be put into
1009 * the current workspace.
1012 ((pCD->transientLeader && GetLeaderPresence(pCD, &pIDs, &numIDs)) ||
1013 ((manageFlags & MANAGEW_WM_RESTART) &&
1014 GetMyOwnPresence (pCD, &pIDs, &numIDs)) ||
1015 (WorkspaceIsInCommand (DISPLAY, pCD, &pIDs, &numIDs)) ||
1018 (HasProperty (pCD, wmGD.xa_DT_WORKSPACE_HINTS) ||
1020 XmInternAtom (DISPLAY, _XA_VUE_WORKSPACE_HINTS,
1023 HasProperty (pCD, wmGD.xa_DT_WORKSPACE_HINTS)
1025 && (GetWorkspaceHints (DISPLAY, pCD->client, &pIDs, &numIDs, &bAll) ==
1030 * Got some workspace hints!
1032 pCD->putInAll = bAll;
1033 ProcessWorkspaceHintList (pCD, pIDs, numIDs);
1036 if (pCD->numInhabited == 0)
1039 * If not in any workspaces, then put the client into
1042 PutClientIntoWorkspace (pCD->pSD->pActiveWS, pCD);
1047 } /* END OF FUNCTION GetClientWorkspaceInfo */
1050 /*************************************<->*************************************
1052 * WorkspaceIsInCommand (dpy, pCD, ppIDs, pNumIDs)
1057 * Determine if workspace specification is in command line for client
1062 * dpy - pointer to display structure
1063 * pCD - ptr to client data
1064 * ppIDs - pointer for returning list of IDs
1065 * pNumIDs - number of IDs being returned
1069 * ppIDs - returned list of IDs
1070 * pNumIDs - number of IDs being returned
1072 * Return - True if workspace option found, false otherwise
1077 * Malloc's memory that must be freed
1079 *************************************<->***********************************/
1082 WorkspaceIsInCommand(
1085 WorkspaceID **ppIDs,
1086 unsigned int *pNumIDs )
1089 char **wmcArgv = NULL;
1090 Boolean rval = False;
1091 unsigned char *pch = NULL;
1092 XTextProperty clientMachineProp;
1094 if (FindClientDBMatch(pCD, (char **)&pch))
1098 if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
1102 XtFree((char *)pch);
1105 else if (HasProperty (pCD, XA_WM_COMMAND) &&
1106 XGetCommand (dpy, pCD->client, &wmcArgv, &wmcArgc) &&
1109 if (pCD->pSD->remainingSessionItems)
1111 if(!(XGetWMClientMachine(dpy, pCD->client, &clientMachineProp)))
1113 clientMachineProp.value = NULL;
1115 if (FindDtSessionMatch(wmcArgc, wmcArgv, pCD, pCD->pSD,
1117 (char *)clientMachineProp.value))
1120 * If we found a match to a client description
1121 * in the DtSessionHints, use the information from
1122 * the Hints instead of the command line
1126 if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
1131 * free malloced memory containing workspace list
1133 XtFree ((char *)pch);
1137 if (clientMachineProp.value)
1139 XFree ((char*)clientMachineProp.value);
1143 if (!rval && FindWsNameInCommand (wmcArgc, wmcArgv, &pch))
1145 if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
1151 if (wmcArgv != NULL)
1153 XFreeStringList (wmcArgv);
1158 } /* END OF FUNCTION WorkspaceIsInCommand */
1161 /*************************************<->*************************************
1163 * ConvertNamesToIDs (pSD, pch, ppAtoms, pNumAtoms)
1168 * Takes a string containing a list of names separated by white space
1169 * and converts it to a list of workspace IDs.
1173 * pSD - pointer to screen data
1174 * pchIn - pointer to original string
1175 * ppAtoms - pointer to an atom pointer (for returning list pointer)
1176 * pNumAtoms - pointer to the number of atoms being returned.
1180 * *ppAtoms - points to a list of atoms returned.
1181 * *pNumAtoms - the number of atoms being returned.
1183 * Return - True if some Atoms are being returned
1187 * Processes local copy of string so that pch is not modified.
1189 * The list of atoms returned has been dynamically allocated.
1190 * Please XtFree() it when you're done.
1192 *************************************<->***********************************/
1197 unsigned char *pchIn,
1198 WorkspaceID **ppAtoms,
1199 unsigned int *pNumAtoms )
1202 unsigned char *pchLocal, *pch, *pchName;
1205 WorkspaceID *pLocalIDs;
1207 if ((pLocalIDs = (WorkspaceID *) XtMalloc (WS_ALLOC_AMOUNT *
1208 sizeof(WorkspaceID))) == NULL)
1210 Warning (((char *)GETMESSAGE(76, 5, "Insufficient Memory (ConvertNamesToIDs)")));
1211 ExitWM (WM_ERROR_EXIT_VALUE);
1213 numLocalIDs = WS_ALLOC_AMOUNT;
1215 if (pchIn && (pchLocal = (unsigned char *) XtMalloc(1+strlen((char *)pchIn))))
1217 strcpy ((char *)pchLocal, (char *)pchIn);
1220 while ((pchName = GetSmartString (&pch)))
1226 * Check workspace for workspace titles; map to
1229 xms = XmStringCreateLocalized ((char *)pchName);
1230 for (iwsx = 0; iwsx < pSD->numWorkspaces; iwsx++)
1232 if (XmStringCompare (xms, pSD->pWS[iwsx].title))
1239 if (iwsx < pSD->numWorkspaces)
1242 * Found a workspace title we've got,
1243 * use id for workspace name
1245 pLocalIDs[num] = pSD->pWS[iwsx].id;
1251 * Try for match on workspace name
1253 pLocalIDs[num] = (WorkspaceID)
1254 XInternAtom (DISPLAY, (char *)pchName, False);
1258 if (num >= numLocalIDs)
1260 /* list too small */
1261 numLocalIDs += WS_ALLOC_AMOUNT;
1262 if ((pLocalIDs = (WorkspaceID *) XtRealloc ((char *)pLocalIDs,
1263 numLocalIDs * sizeof(WorkspaceID))) == NULL)
1265 Warning (((char *)GETMESSAGE(76, 6, "Insufficient Memory (ConvertNamesToIDs)")));
1266 ExitWM (WM_ERROR_EXIT_VALUE);
1271 XtFree ((char *)pchLocal);
1274 *ppAtoms = pLocalIDs;
1278 } /* END OF FUNCTION ConvertNamesToIDs */
1281 /*************************************<->*************************************
1283 * CheckForPutInAllRequest (pCD, pIDs, numIDs)
1288 * Tests for the presence of the "all" atom in the atom list
1289 * and sets the "putInAll" flag on the client.
1293 * pCD - pointer to client data
1294 * pIDs - pointer to ID list
1295 * numIDs - number of IDs in list
1299 * pCD - putInAll member may be set
1301 *************************************<->***********************************/
1304 CheckForPutInAllRequest(
1307 unsigned int numIDs )
1312 for (i = 0; (i < numIDs) && !(pCD->putInAll); i++)
1314 if (pIDs[i] == wmGD.xa_ALL_WORKSPACES)
1316 pCD->putInAll = True;
1321 } /* END OF FUNCTION CheckForPutInAllRequest */
1324 /*************************************<->*************************************
1326 * FindWsNameInCommand (argc, argv, ppch)
1331 * Finds and returns the workspace name option in the command line
1336 * argc - argument count
1337 * argv - argument list
1338 * ppch - string pointer to return
1343 * *ppch - points to ws name (if found)
1345 * Return - True if wsname found
1350 *************************************<->***********************************/
1353 FindWsNameInCommand(
1356 unsigned char **ppch )
1360 #define XRM_OPT "-xrm"
1361 #define WSLIST "*workspaceList:"
1362 #define WSLIST_LEN 14
1365 Boolean rval = False;
1366 unsigned char *pch, *pchTmp, *pch0;
1367 unsigned char *pchRes, *pchValue;
1371 while (--argc && !rval)
1373 if (!strcmp(argv[i], XRM_OPT) && (argc > 1))
1376 * found "-xrm", now look at resource spec
1378 pch0 = (unsigned char *) strdup (argv[i+1]);
1381 Warning (((char *)GETMESSAGE(76, 7, "Insufficient memory")));
1382 ExitWM (WM_ERROR_EXIT_VALUE);
1386 /* strip off quotes ,
1387 * separate two halve of resource spec
1389 pchRes = GetSmartString (&pch);
1392 if ((*pchRes) && (*pch))
1394 /* Erase colon at end of resource name */
1396 pch = (unsigned char *) strrchr((char *)pchRes, ':');
1402 /* find beginning of last component of resource
1405 pch = (unsigned char *) strrchr ((char *)pchRes, '*');
1406 pchTmp = (unsigned char *) strrchr ((char *)pchRes, '.');
1412 if (pch && *pch && *(pch+1))
1417 /* compare resource with our resource */
1419 if ( (!strcmp ((char *)pch, WmNworkspaceList)) ||
1420 (!strcmp ((char *)pch, WmCWorkspaceList)))
1422 /* match, compute return position in
1425 *ppch = (unsigned char *)
1426 (argv[i+1] + (pchValue - pch0));
1428 XtFree ((char *)pch0);
1433 i++; /* skip next arg */
1438 XtFree ((char *)pch0);
1445 } /* END OF FUNCTION FindWsNameInCommand */
1449 /*************************************<->*************************************
1451 * PutClientIntoWorkspace (pWS, pCD)
1456 * This function updates the data for the client and workspace to
1457 * reflect the presence of the client in the workspace.
1461 * pWS = pointer to workspace data
1462 * pCD = pointer to client data
1467 *************************************<->***********************************/
1470 PutClientIntoWorkspace(
1471 WmWorkspaceData *pWS,
1475 int i = pCD->numInhabited;
1478 /* insure the client's got enough workspace data */
1479 if (pCD->sizeWsList < pCD->pSD->numWorkspaces)
1481 iAdded = pCD->pSD->numWorkspaces - pCD->sizeWsList;
1483 pCD->sizeWsList = pCD->pSD->numWorkspaces;
1484 pCD->pWsList = (WsClientData *)
1485 XtRealloc((char *)pCD->pWsList,
1486 (pCD->pSD->numWorkspaces * sizeof(WsClientData)));
1488 /* intialized new data */
1489 j = pCD->sizeWsList - 1;
1490 for (j=1; j <= iAdded; j++)
1492 k = pCD->sizeWsList - j;
1493 pCD->pWsList[k].iconPlace = NO_ICON_PLACE;
1494 pCD->pWsList[k].iconX = 0;
1495 pCD->pWsList[k].iconY = 0;
1496 pCD->pWsList[k].iconFrameWin = (Window) 0;
1497 pCD->pWsList[k].pIconBox = NULL;
1502 /* update the client's list of workspace data */
1503 pCD->pWsList[i].wsID = pWS->id;
1504 pCD->numInhabited++;
1506 if (!(pCD->clientFlags & WM_INITIALIZATION))
1509 * Make sure there's an icon
1510 * (Don't do this during initialization, the pCD not
1511 * ready for icon making yet).
1513 InsureIconForWorkspace (pWS, pCD);
1516 /* update the workspace list of clients */
1517 AddClientToWsList (pWS, pCD);
1519 } /* END OF FUNCTION PutClientIntoWorkspace */
1522 /*************************************<->*************************************
1524 * TakeClientOutOfWorkspace (pWS, pCD)
1529 * This function updates the data for the client and the workspace
1530 * to reflect the removal of the client from the workspace.
1534 * pWS = pointer to workspace data
1535 * pCD = pointer to client data
1540 *************************************<->***********************************/
1543 TakeClientOutOfWorkspace(
1544 WmWorkspaceData *pWS,
1549 Boolean Copying = False;
1552 if (pWS && pCD && ClientInWorkspace(pWS, pCD))
1557 if (!pCD->transientLeader)
1559 pWsc = GetWsClientData (pWS, pCD);
1561 if ((pCD->pSD->useIconBox) &&
1563 (pCD->clientFunctions & MWM_FUNC_MINIMIZE))
1565 DeleteIconFromBox (pWS->pIconBox, pCD);
1567 else if (wmGD.iconAutoPlace)
1570 * Free up root icon spot
1573 if ((pWsc->iconPlace != NO_ICON_PLACE) &&
1574 (pWS->IPData.placeList[pWsc->iconPlace].pCD == pCD))
1576 pWS->IPData.placeList[pWsc->iconPlace].pCD = NULL;
1577 pWsc->iconPlace = NO_ICON_PLACE;
1583 * Remove the selected workspace and copy the remaining ones
1584 * up. (Do piece-wise to avoid overlapping copy.)
1586 for (ixA = 0; ixA < pCD->numInhabited; ixA++)
1590 memcpy (&pCD->pWsList[ixA-1], &pCD->pWsList[ixA],
1591 sizeof(WsClientData));
1593 else if (pCD->pWsList[ixA].wsID == pWS->id)
1596 * This is the one we're removing, start copying here.
1603 * Decrement the number of workspaces inhabited.
1605 pCD->numInhabited--;
1607 /* update the workspaces list of clients */
1608 RemoveClientFromWsList (pWS, pCD);
1613 Warning("TakeClientOutOfWorkspace: null workspace passed in.");
1618 } /* END OF FUNCTION TakeClientOutOfWorkspace */
1621 /*************************************<->*************************************
1623 * GetWorkspaceData (pSD, wsID)
1628 * This function finds the data that is associated with a workspace ID.
1632 * pSD = pointer to screen data
1633 * wsID = workspace ID
1637 * Function returns a pointer to the workspace data if successful,
1638 * or NULL if unsuccessful.
1640 *************************************<->***********************************/
1648 WmWorkspaceData *pWS = NULL;
1651 for (i=0; i < pSD->numWorkspaces; i++)
1653 if (pSD->pWS[i].id == wsID)
1663 /* failed to find one */
1664 Warning ("Failed to find workspace data");
1670 } /* END OF FUNCTION GetWorkspaceData */
1674 /*************************************<->*************************************
1676 * GenerateWorkspaceName (pSD, wsnum)
1681 * This function generates and returns a workspace string name from
1682 * a small number passed in.
1686 * pSD = pointer to screen data
1687 * wsNum = number for workspace
1692 * returns pointer to statically allocated data. You must copy it
1693 * to your local buffer.
1697 * Name is of the form ws<n> where <n> is a number.
1699 *************************************<->***********************************/
1702 GenerateWorkspaceName(
1707 static unsigned char nameReturned[10];
1711 * Nice n-squared algorithm...
1712 * (This should be OK for small number of workspaces)
1714 for (i=0; i <= pSD->numWorkspaces; i++)
1716 /* generate a name */
1717 sprintf ((char *)nameReturned, "ws%d", i);
1718 if (!DuplicateWorkspaceName (pSD, nameReturned, wsnum))
1722 return (nameReturned);
1724 } /* END OF FUNCTION GenerateWorkspaceName */
1728 /*************************************<->*************************************
1730 * InWindowList (w, wl, num)
1735 * This function determines if a window is in a list of windows
1739 * w = window of interest
1740 * wl = list of windows
1741 * num = number of windows in wl
1746 * The function returns "True" if "w" appears in "wl"
1748 *************************************<->***********************************/
1758 Boolean rval = False;
1760 for (i = 0; (i < num) && !rval; i++)
1770 } /* END OF FUNCTION InWindowList */
1773 /*************************************<->*************************************
1775 * ClientInWorkspace (pWS, pCD)
1780 * This function determines if a client is in a workspace
1784 * pWS = pointer to workspace data
1785 * pCD = pointer to client data
1789 * The function returns "True" if client pCD is in workspace pWS
1791 *************************************<->***********************************/
1795 WmWorkspaceData *pWS,
1800 Boolean rval = False;
1802 for (i = 0; (i < pCD->numInhabited) && !rval; i++)
1804 if (pWS->id == pCD->pWsList[i].wsID)
1812 } /* END OF FUNCTION ClientInWorkspace */
1815 /*************************************<->*************************************
1817 * GetWsClientData (pWS, pCD)
1822 * This function returns a pointer to the client's specific data for
1827 * pWS = pointer to workspace data
1828 * pCD = pointer to client data
1832 * The function returns a pointer to the client's data for this
1833 * workspace. If the client isn't in the workspace, an error is
1834 * printed and the first datum in the workspace list is returned.
1836 *************************************<->***********************************/
1840 WmWorkspaceData *pWS,
1845 WsClientData *pWsc = NULL;
1847 for (i = 0; (i < pCD->numInhabited) && !pWsc; i++)
1849 if (pWS->id == pCD->pWsList[i].wsID)
1851 pWsc = &pCD->pWsList[i];
1857 pWsc = &pCD->pWsList[0];
1862 } /* END OF FUNCTION GetWsClientData */
1865 /*************************************<->*************************************
1867 * SetClientWsIndex (pCD)
1872 * This function sets the index into the client's array of workspace
1873 * specific data. This index points to the data to be used for the
1874 * currently active workspace.
1878 * pCD = pointer to client data
1882 * The function returns an index as described above. If the client is
1883 * not in the currently active workspace, then the index returned is 0.
1885 *************************************<->***********************************/
1893 WmWorkspaceData *pWS = pCD->pSD->pActiveWS;
1895 for (i = 0; (i < pCD->numInhabited); i++)
1897 if (pWS->id == pCD->pWsList[i].wsID)
1903 if (i >= pCD->numInhabited)
1908 pCD->currentWsc = i;
1910 } /* END OF FUNCTION SetClientWsIndex */
1914 /*************************************<->*************************************
1916 * ProcessWmWorkspaceHints (pCD)
1921 * This function processes a change to the _DT_WORKSPACE_HINTS property
1922 * on a window that we manage.
1926 * pCD = pointer to client data
1930 * Returns False if we ran out of memory or no hints.
1931 * Returns True on success.
1933 *************************************<->***********************************/
1936 ProcessWorkspaceHints(
1942 unsigned int numIDs;
1943 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
1944 Boolean rval = False;
1948 WorkspaceID *pDiff = NULL;
1951 numOld = pCD->numInhabited;
1952 ReserveIdListSpace (numOld);
1953 for (i = 0; i < numOld; i++)
1955 pResIDs[i] = pCD->pWsList[i].wsID;
1958 if ((pCD->client) &&
1959 (GetWorkspaceHints (DISPLAY, pCD->client,
1960 &pIDs, &numIDs, &bAll) == Success) &&
1961 (bAll || (numIDs && (pDiff = (WorkspaceID *)
1962 XtMalloc (sizeof(WorkspaceID) * MAX(numIDs, numOld))))))
1965 * Process request to put window in all workspaces
1967 pCD->putInAll = bAll;
1968 CheckForPutInAllRequest (pCD, pIDs, numIDs);
1973 * Compute the ids to be removed.
1977 for (i=0; i < numOld; i++)
1980 for (j=0; j < numIDs; j++)
1982 if (pIDs[j] == pResIDs[i])
1991 pDiff[numDiff++] = pResIDs[i];
1996 * Remove the client from the set of workspaces
2000 RemoveClientFromWorkspaces (pCD, pDiff, numDiff);
2005 * Process request to put window in all workspaces
2010 for (i=0; i<pCD->pSD->numWorkspaces; i++)
2012 if (!ClientInWorkspace(&pCD->pSD->pWS[i], pCD))
2014 AddClientToWorkspaces (pCD, &pCD->pSD->pWS[i].id, 1);
2021 * Compute the ids to be added.
2025 for (i=0; i < numIDs; i++)
2028 for (j=0; j < numOld; j++)
2030 if (pResIDs[j] == pIDs[i])
2039 pDiff[numDiff++] = pIDs[i];
2044 * Add the client to the set of workspaces
2048 AddClientToWorkspaces (pCD, pDiff, numDiff);
2053 * If the client is not in any workspaces, then
2054 * put it in the current one
2056 * !!! Is this right? !!!
2058 if (pCD->numInhabited == 0)
2060 AddClientToWorkspaces (pCD, &pSD->pActiveWS->id, 1);
2064 * Free up the old list of hints
2066 if (pCD->pWorkspaceHints)
2068 XFree ((char *)pCD->pWorkspaceHints);
2072 XtFree ((char *)pDiff);
2076 * Save the new hints
2078 pCD->pWorkspaceHints = pIDs;
2079 pCD->numWorkspaceHints = numIDs;
2082 * Update the presence property
2084 UpdateWorkspacePresenceProperty (pCD);
2090 } /* END OF FUNCTION ProcessWorkspaceHints */
2093 /*************************************<->*************************************
2095 * InsureUniqueWorkspaceHints (pCD)
2100 * This function processes the workspace hints and removes duplicates.
2104 * pCD = pointer to client data
2108 * May modify *pWorkspaceHints and numWorkspaceHints
2110 *************************************<->***********************************/
2113 InsureUniqueWorkspaceHints(
2122 if (pCD->numWorkspaceHints < 2) return;
2124 pID = pCD->pWorkspaceHints;
2129 while (next < pCD->numWorkspaceHints)
2132 for (i = 0; i < next; i++)
2134 if (pID [next] == pID [i])
2136 /* duplicate found! */
2144 /* skip duplicates */
2149 /* not a duplicate */
2154 * We need to copy up over an old duplicate
2156 pID [trail] = pID [next];
2162 pCD->numWorkspaceHints = trail+1;
2164 } /* END OF FUNCTION InsureUniqueWorkspaceHints */
2168 /*************************************<->*************************************
2170 * ProcessWorkspaceHintList (pCD, pIDs, numIDs)
2175 * This function processes a list of workspace hints for a client.
2179 * pCD = pointer to client data
2180 * pIDs = pointer to a list of workspace IDs
2181 * numIDs = number of IDs in the list
2186 *************************************<->***********************************/
2189 ProcessWorkspaceHintList(
2192 unsigned int numIDs )
2196 WmWorkspaceData *pWS;
2202 * Keep these hints; make sure there are no duplicate
2203 * workspace requests.
2205 pCD->pWorkspaceHints = pIDs;
2206 pCD->numWorkspaceHints = numIDs;
2207 InsureUniqueWorkspaceHints (pCD);
2208 numIDs = pCD->numWorkspaceHints;
2210 if (pCD->pWorkspaceHints)
2213 * Process request to put window in all workspaces
2215 CheckForPutInAllRequest (pCD, pIDs, numIDs);
2219 for (i=0; i<pCD->pSD->numWorkspaces; i++)
2221 PutClientIntoWorkspace (&pCD->pSD->pWS[i], pCD);
2226 for (i=0; i<numIDs; i++)
2229 * Put the client into requested workspaces that
2232 if ((pWS = GetWorkspaceData (pCD->pSD,
2233 pCD->pWorkspaceHints[i])))
2235 PutClientIntoWorkspace (pWS, pCD);
2242 } /* END OF FUNCTION ProcessWorkspaceHintList */
2245 /*************************************<->*************************************
2247 * RemoveSingleClientFromWorkspaces (pCD, pIDs, numIDs)
2252 * This function removes a single client from a list of workspaces
2256 * pCD = pointer to client data
2257 * pIDs = pointer to a list of workspace IDs
2258 * numIDs = number of workspace IDs
2263 *************************************<->***********************************/
2266 RemoveSingleClientFromWorkspaces(
2269 unsigned int numIDs )
2273 WmWorkspaceData *pWS;
2275 for (i=0; i < numIDs; i++)
2278 * Remove the client from the specified workspaces
2280 if ((pWS = GetWorkspaceData (pCD->pSD, pIDs[i])) &&
2281 (ClientInWorkspace (pWS, pCD)))
2284 * If this workspace is active, then make the
2285 * window unseen. We only need to call
2286 * SetClientState on the main window, the
2287 * transients will get taken care of in there.
2289 if ((pWS == pCD->pSD->pActiveWS) &&
2290 (pCD->transientLeader == NULL) &&
2291 !(pCD->clientState & UNSEEN_STATE))
2293 SetClientState (pCD,
2294 (pCD->clientState | UNSEEN_STATE), CurrentTime);
2296 TakeClientOutOfWorkspace (pWS, pCD);
2299 * Update the presence property
2301 UpdateWorkspacePresenceProperty (pCD);
2305 } /* END OF FUNCTION RemoveSingleClientFromWorkspaces */
2307 /*************************************<->*************************************
2309 * RemoveSubtreeFromWorkspaces (pCD, pIDs, numIDs)
2314 * This function removes a transient subtree from a list of workspaces
2318 * pCD = pointer to client data
2319 * pIDs = pointer to a list of workspace IDs
2320 * numIDs = number of workspace IDs
2325 *************************************<->***********************************/
2328 RemoveSubtreeFromWorkspaces(
2331 unsigned int numIDs )
2336 pNext = pCD->transientChildren;
2339 /* process all children first */
2340 if (pNext->transientChildren)
2342 RemoveSubtreeFromWorkspaces (pNext, pIDs, numIDs);
2346 RemoveSingleClientFromWorkspaces (pNext, pIDs, numIDs);
2348 pNext = pNext->transientSiblings;
2351 /* process the primary window */
2352 RemoveSingleClientFromWorkspaces (pCD, pIDs, numIDs);
2355 } /* END OF FUNCTION RemoveSubtreeFromWorkspaces */
2360 /******************************<->*************************************
2362 * pIDs = GetListOfOccupiedWorkspaces (pCD, numIDs)
2367 * This function creates a list of occupied workspaces of a particular
2368 * client, EXCLUDING the current workspace.
2372 * pCD = pointer to client data
2376 * pIDs = pointer to a list of workspace IDs
2377 * numIDs = number of workspace IDs
2381 * memory for pIDs is allocated with XtMalloc and should be
2382 * freed with XtFree.
2385 ******************************<->***********************************/
2387 GetListOfOccupiedWorkspaces(
2393 WorkspaceID *pLocalIDs = NULL;
2395 WorkspaceID activeWsID = pCD->pSD->pActiveWS->id;
2399 if ((pLocalIDs = (WorkspaceID *) XtMalloc (pCD->numInhabited *
2400 sizeof(WorkspaceID))) == NULL)
2402 Warning (((char *)GETMESSAGE(76, 7, "Insufficient memory")));
2406 for (i = 0; i < pCD->numInhabited; i++)
2408 if (activeWsID != pCD->pWsList[i].wsID)
2410 pLocalIDs[(*numIDs)++] = pCD->pWsList[i].wsID;
2416 } /* END OF FUNCTION GetListOfOccupiedWorkspaces */
2417 #endif /* PANELIST */
2420 /******************************<->*************************************
2422 * HonorAbsentMapBehavior(pCD)
2427 * This function adds a client to the current workspace and
2428 * if (pCD->absentMapBehavior == AMAP_BEHAVIOR_MOVE)
2429 * removes the client from the other workspaces
2434 * pCD = pointer to client data
2439 ******************************<->***********************************/
2442 HonorAbsentMapBehavior(
2445 int inWorkspace = 0;
2447 if (pCD->absentMapBehavior == AMAP_BEHAVIOR_MOVE)
2452 * Remove from other workspaces
2454 for (wsCnt = 0; wsCnt < pCD->numInhabited; wsCnt = inWorkspace)
2456 if (pCD->pWsList[wsCnt].wsID != pCD->pSD->pActiveWS->id)
2458 RemoveClientFromWorkspaces (pCD,
2459 &pCD->pWsList[wsCnt].wsID, 1);
2465 if (inWorkspace == 0)
2466 AddClientToWorkspaces (pCD, &ACTIVE_WS->id, 1);
2468 } /* END OF FUNCTION HonorAbsentMapBehavior */
2472 /******************************<->*************************************
2474 * RemoveClientFromWorkspaces (pCD, pIDs, numIDs)
2479 * This function removes a client from a list of workspaces
2483 * pCD = pointer to client data
2484 * pIDs = pointer to a list of workspace IDs
2485 * numIDs = number of workspace IDs
2490 ******************************<->***********************************/
2493 RemoveClientFromWorkspaces(
2496 unsigned int numIDs )
2499 ClientData *pcdLeader;
2501 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
2503 RemoveSubtreeFromWorkspaces (pcdLeader, pIDs, numIDs);
2506 } /* END OF FUNCTION RemoveClientFromWorkspaces */
2509 /*************************************<->*************************************
2511 * AddSingleClientToWorkspaces (pCD, pIDs, numIDs)
2516 * This function adds a single client to a list of workspaces
2520 * pCD = pointer to client data
2521 * pIDs = pointer to a list of workspace IDs
2522 * numIDs = number of workspace IDs
2527 *************************************<->***********************************/
2530 AddSingleClientToWorkspaces(
2533 unsigned int numIDs )
2537 WmWorkspaceData *pWS;
2539 for (i=0; i < numIDs; i++)
2542 * Add the client to the specified workspaces if
2543 * it is not already there.
2545 if ((pWS = GetWorkspaceData (pCD->pSD, pIDs[i])) &&
2546 (!ClientInWorkspace (pWS, pCD)))
2548 PutClientIntoWorkspace (pWS, pCD);
2550 if ((pWS == PSD_FOR_CLIENT(pCD)->pActiveWS) &&
2551 (pCD->transientLeader == NULL) &&
2552 (pCD->clientState & UNSEEN_STATE))
2554 SetClientState (pCD,
2555 (pCD->clientState & ~UNSEEN_STATE), CurrentTime);
2559 * Update the presence property (only on transient leader)
2561 UpdateWorkspacePresenceProperty (pCD);
2565 } /* END OF FUNCTION AddSingleClientToWorkspace */
2568 /*************************************<->*************************************
2570 * AddSubtreeToWorkspaces (pCD, pIDs, numIDs)
2575 * This function adds a client subtree to a list of workspaces
2579 * pCD = pointer to client data (head of subtree)
2580 * pIDs = pointer to a list of workspace IDs
2581 * numIDs = number of workspace IDs
2586 *************************************<->***********************************/
2589 AddSubtreeToWorkspaces(
2592 unsigned int numIDs )
2597 pNext = pCD->transientChildren;
2600 /* process all children first */
2601 if (pNext->transientChildren)
2603 AddSubtreeToWorkspaces (pNext, pIDs, numIDs);
2607 AddSingleClientToWorkspaces (pNext, pIDs, numIDs);
2609 pNext = pNext->transientSiblings;
2612 /* process the primary window */
2613 AddSingleClientToWorkspaces (pCD, pIDs, numIDs);
2616 } /* END OF FUNCTION AddSubtreeToWorkspaces */
2619 /*************************************<->*************************************
2621 * AddClientToWorkspaces (pCD, pIDs, numIDs)
2626 * This function adds a transient tree to a list of workspaces
2630 * pCD = pointer to client data
2631 * pIDs = pointer to a list of workspace IDs
2632 * numIDs = number of workspace IDs
2637 *************************************<->***********************************/
2640 AddClientToWorkspaces(
2643 unsigned int numIDs )
2646 ClientData *pcdLeader;
2648 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
2650 AddSubtreeToWorkspaces (pcdLeader, pIDs, numIDs);
2652 } /* END OF FUNCTION AddClientToWorkspaces */
2656 /*************************************<->*************************************
2658 * AddClientToWsList (pWS, pCD)
2663 * This function adds a client to a list of clients in a workspace
2667 * pCD = pointer to client data
2668 * pWS = pointer to workspace data
2674 *************************************<->***********************************/
2678 WmWorkspaceData *pWS,
2682 if (pWS->numClients >= pWS->sizeClientList)
2684 if (pWS->sizeClientList == 0)
2686 pWS->ppClients = (ClientData **)
2687 XtMalloc (WINDOW_ALLOC_AMOUNT * sizeof(ClientData *));
2691 pWS->ppClients = (ClientData **)
2692 XtRealloc ((char *)pWS->ppClients,
2693 (pWS->sizeClientList + WINDOW_ALLOC_AMOUNT) *
2694 sizeof(ClientData *));
2697 if (!pWS->ppClients)
2699 Warning (((char *)GETMESSAGE(76, 9, "Insufficient memory to add window to workspace")));
2700 ExitWM(WM_ERROR_EXIT_VALUE);
2703 pWS->sizeClientList += WINDOW_ALLOC_AMOUNT;
2706 if (pWS->numClients < pWS->sizeClientList)
2708 pWS->ppClients[pWS->numClients] = pCD;
2711 } /* END OF FUNCTION AddClientToWsList */
2714 /*************************************<->*************************************
2716 * RemoveClientFromWsList (pWS, pCD)
2721 * This function removes a client from a list of clients in a workspace
2725 * pCD = pointer to client data
2726 * pWS = pointer to workspace data
2732 *************************************<->***********************************/
2735 RemoveClientFromWsList(
2736 WmWorkspaceData *pWS,
2742 for (dest = 0; dest < pWS->numClients; dest++)
2744 if (pWS->ppClients[dest] == pCD)
2750 for (src = dest+1; src < pWS->numClients; src++, dest++)
2752 pWS->ppClients[dest] = pWS->ppClients[src];
2757 } /* END OF FUNCTION RemoveClientFromWsList */
2760 /*************************************<->*************************************
2763 * F_CreateWorkspace (args, pCD, event)
2781 *************************************<->***********************************/
2790 WmScreenData *pSD = ACTIVE_PSD;
2792 if (pSD->numWorkspaces >= MAX_WORKSPACE_COUNT)
2794 char buffer[MAXWMPATH];
2796 * At the maximum number of allowed workspaces.
2799 ((char *)GETMESSAGE(76, 14, "Maximum number of workspaces is %d. New workspace was not created.")), MAX_WORKSPACE_COUNT);
2804 CreateWorkspace (ACTIVE_PSD, (unsigned char *)args);
2809 } /* END OF FUNCTION F_CreateWorkspace */
2812 /*************************************<->*************************************
2815 * F_DeleteWorkspace (args, pCD, event)
2833 *************************************<->***********************************/
2842 WmScreenData *pSD = ACTIVE_PSD;
2843 WmWorkspaceData *pWS = NULL;
2852 for (i=0; i<pSD->numWorkspaces; i++)
2854 if (!strcmp(pSD->pWS[i].name, args))
2856 pWS = &(pSD->pWS[i]);
2863 DeleteWorkspace (pWS);
2867 } /* END OF FUNCTION F_DeleteWorkspace */
2870 /*************************************<->*************************************
2873 * F_GotoWorkspace (args, pCD, event)
2891 *************************************<->***********************************/
2901 WmWorkspaceData *pWS;
2903 wsID = XInternAtom (DISPLAY, args, False);
2904 pWS = GetWorkspaceData (ACTIVE_PSD, wsID);
2908 ChangeToWorkspace (pWS);
2912 } /* END OF FUNCTION F_GotoWorkspace */
2917 /*************************************<->*************************************
2920 * F_AddToAllWorkspaces (args, pCD, event)
2925 * Puts a client into all workspaces
2931 * pCD = pointer to client data
2942 * The list of Ids returned has been privately allocated. Copy
2943 * if you want to save or do anything with it.
2945 *************************************<->***********************************/
2948 F_AddToAllWorkspaces(
2957 if (pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS))
2961 ReserveIdListSpace (pSD->numWorkspaces);
2963 for (i = 0; i < pSD->numWorkspaces; i++)
2965 pResIDs[i] = pSD->pWS[i].id;
2968 AddClientToWorkspaces (pCD, pResIDs, pSD->numWorkspaces);
2970 pCD->putInAll = True;
2975 } /* END OF FUNCTION F_AddToAllWorkspaces */
2978 /*************************************<->*************************************
2981 * F_Remove (args, pCD, event)
2986 * Removes a client from the current workspace
2992 * pCD = pointer to client data
3004 *************************************<->***********************************/
3013 Boolean rval = False;
3016 * Only remove if in more than one workspace.
3018 if ((pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS)) &&
3019 (pCD->numInhabited > 1))
3021 if (ClientInWorkspace (ACTIVE_WS, pCD))
3023 RemoveClientFromWorkspaces (pCD, &ACTIVE_WS->id, 1);
3024 pCD->putInAll = False;
3030 } /* END OF FUNCTION F_Remove */
3034 /*************************************<->*************************************
3036 * GetCurrentWorkspaceIndex (pSD)
3041 * Returns an index into the screens array of workspace structures
3042 * for the current workspace.
3055 *************************************<->***********************************/
3057 GetCurrentWorkspaceIndex(
3063 for (i = 0 ; i < pSD->numWorkspaces; i++)
3065 if (pSD->pWS[i].id == pSD->pActiveWS->id)
3069 if (i >= pSD->numWorkspaces)
3071 /* failed to find workspace!!! How did that happen??? */
3074 Warning ("Failed to find workspace index");
3079 } /* END OF FUNCTION GetCurrentWorkspaceIndex */
3082 /*************************************<->*************************************
3085 * InsureIconForWorkspace (pWS, pCD)
3090 * Makes sure an icon exists for the workspace
3103 *************************************<->***********************************/
3106 InsureIconForWorkspace(
3107 WmWorkspaceData *pWS,
3113 if (pCD->clientFunctions & MWM_FUNC_MINIMIZE)
3115 pWsc = GetWsClientData (pWS, pCD);
3117 if ((pCD->pSD->useIconBox) &&
3118 (!(pCD->clientFlags & (CLIENT_WM_CLIENTS | FRONT_PANEL_BOX))))
3121 * Create a new widget for the icon box
3123 if (MakeIcon (pWS, pCD))
3125 XSaveContext (DISPLAY, pWsc->iconFrameWin,
3126 wmGD.windowContextType, (caddr_t)pCD);
3128 if (pCD->iconWindow && pWsc->iconFrameWin)
3130 XGrabButton (DISPLAY, AnyButton, AnyModifier,
3131 pWsc->iconFrameWin, True,
3132 ButtonPressMask|ButtonReleaseMask|
3134 GrabModeAsync, GrabModeAsync, None,
3135 wmGD.workspaceCursor);
3138 ShowClientIconState (pCD, (pCD->clientState & ~UNSEEN_STATE));
3144 * Reuse existing icon in new workspaces. Suggest
3145 * icon position in current WS as position of icon
3148 pWsc->iconFrameWin = pCD->pWsList[0].iconFrameWin;
3149 pWsc->iconX = ICON_X(pCD);
3150 pWsc->iconY = ICON_Y(pCD);
3152 if ((pCD->clientState & ~UNSEEN_STATE) != MINIMIZED_STATE)
3154 pWsc->iconPlace = NO_ICON_PLACE;
3156 else if (!wmGD.iconAutoPlace)
3158 if (wmGD.positionIsFrame)
3160 pWsc->iconX -= pCD->clientOffset.x;
3161 pWsc->iconY -= pCD->clientOffset.y;
3163 PlaceIconOnScreen (pCD, &pWsc->iconX, &pWsc->iconY);
3165 else /* icon auto placement */
3168 CvtIconPositionToPlace (&pWS->IPData,
3169 pWsc->iconX, pWsc->iconY);
3170 if (pWS->IPData.placeList[pWsc->iconPlace].pCD)
3172 /* The spot is already occupied! Find a
3175 FindIconPlace (pCD, &pWS->IPData, pWsc->iconX,
3178 if (pWsc->iconPlace == NO_ICON_PLACE)
3180 /* Can't find a spot close by. Use the
3181 next available slot */
3182 pWsc->iconPlace = GetNextIconPlace (&pWS->IPData);
3183 if (pWsc->iconPlace == NO_ICON_PLACE)
3186 CvtIconPositionToPlace (&pWS->IPData,
3192 CvtIconPlaceToPosition (&pWS->IPData, pWsc->iconPlace,
3193 &pWsc->iconX, &pWsc->iconY);
3196 if (!(pWS->IPData.placeList[pWsc->iconPlace].pCD))
3198 pWS->IPData.placeList[pWsc->iconPlace].pCD = pCD;
3203 } /* END OF FUNCTION InsureIconForWorkspace */
3206 /*************************************<->*************************************
3209 * GetLeaderPresence (pCD, pIDs, pnumIDs)
3214 * Gets the workspace presence of the transient tree leader for a
3220 * pCD = pointer to client data
3221 * ppIDs = pointer to pointer to list of workspace ids
3222 * pnumIDs = pointer to number of workspace ids
3227 * *ppIDS = list of workspace IDs
3228 * *pnumIDs = number of workspace IDs in list
3230 * Return = true on success
3235 * ID list is dynamically allocated, please XtFree() it when you're
3238 *************************************<->***********************************/
3243 WorkspaceID **ppIDs,
3244 unsigned int *pnumIDs )
3247 ClientData *pcdLeader;
3249 Boolean rval = False;
3250 WorkspaceID *pLocalIDs;
3252 if ((pLocalIDs = (WorkspaceID *) XtMalloc (pCD->pSD->numWorkspaces *
3253 sizeof(WorkspaceID))) == NULL)
3255 Warning (((char *)GETMESSAGE(76, 10, "Insufficient Memory (GetLeaderPresence)")));
3256 ExitWM (WM_ERROR_EXIT_VALUE);
3260 * Make up list of workspaces for primary window
3262 if (pCD->transientLeader)
3264 pcdLeader = FindTransientTreeLeader (pCD);
3266 for (i = 0; i < pcdLeader->numInhabited; i++)
3268 pLocalIDs[i] = pcdLeader->pWsList[i].wsID;
3272 *pnumIDs = pcdLeader->numInhabited;
3278 } /* END OF FUNCTION GetLeaderPresence */
3281 /*************************************<->*************************************
3284 * GetMyOwnPresence (pCD, pIDs, pnumIDs)
3289 * Returns the current workspace presence for the client
3294 * pCD = pointer to client data
3295 * ppIDs = pointer to pointer to list of workspace ids
3296 * pnumIDs = pointer to number of workspace ids
3301 * *ppIDS = list of workspace IDs
3302 * *pnumIDs = number of workspace IDs in list
3304 * Return = true on success
3309 * ID list is dynamically allocated (by DtWsmGetWorkspacesOccupied).
3310 * Please XtFree() it when you're done.
3312 *************************************<->***********************************/
3317 WorkspaceID **ppIDs,
3318 unsigned int *pnumIDs )
3321 Boolean rval = False;
3322 unsigned long nIDs = (unsigned long)*pnumIDs;
3325 * Get the workspace presence property
3329 (HasProperty (pCD, wmGD.xa_DT_WORKSPACE_PRESENCE) ||
3331 XmInternAtom (DISPLAY, _XA_VUE_WORKSPACE_PRESENCE,
3334 HasProperty (pCD, wmGD.xa_DT_WORKSPACE_PRESENCE)
3336 && (DtWsmGetWorkspacesOccupied (DISPLAY, pCD->client, ppIDs,
3344 *pnumIDs = (unsigned int)nIDs;
3348 } /* END OF FUNCTION GetMyOwnPresence */
3352 /*************************************<->*************************************
3355 * ReserveIdListSpace (numIDs)
3360 * Insures that there is enough room in our privately allocated
3361 * list of workspace IDs
3366 * numIDs = number of workspace ids
3373 *************************************<->***********************************/
3382 pResIDs = (WorkspaceID *)
3383 XtMalloc (numIDs * sizeof (WorkspaceID));
3389 else if (numResIDs < numIDs)
3391 pResIDs = (WorkspaceID *) XtRealloc ((char *)pResIDs,
3392 numIDs * sizeof (WorkspaceID));
3394 numResIDs = (pResIDs)? numIDs : 0;
3397 if (pResIDs == NULL)
3399 Warning (((char *)GETMESSAGE(76, 11, "Insufficient memory")));
3400 ExitWM (WM_ERROR_EXIT_VALUE);
3403 } /* END OF FUNCTION ReserveIdListSpace */
3408 /******************************<->*************************************
3410 * SaveResources (pSD)
3414 * Saves dtwm resources to restore session
3418 * pSD = pointer to screen data
3427 *************************************<->***********************************/
3429 SaveResources( WmScreenData *pSD)
3433 WmPanelistObject pPanelist;
3434 #endif /* PANELIST */
3440 SaveWorkspaceResources(pSD->pActiveWS,
3441 (WM_RES_INITIAL_WORKSPACE |
3442 WM_RES_WORKSPACE_COUNT));
3446 pPanelist = (WmPanelistObject) pSD->wPanelist;
3447 if (pPanelist && O_Shell(pPanelist))
3449 /* This is the front panel for the screen */
3450 SaveWorkspaceResources(pSD->pActiveWS,
3451 WM_RES_FP_POSITION);
3454 /* Call the fronto panel function to save its resources */
3456 WmFrontPanelSessionSaveData();
3458 #endif /* PANELIST */
3462 for (wsCnt = 0; wsCnt < pSD->numWorkspaces; wsCnt++)
3466 SaveWorkspaceResources(&pSD->pWS[wsCnt],
3467 WM_RES_ICONBOX_GEOMETRY);
3471 SaveHelpResources(pSD);
3475 } /* END OF FUNCTION SaveResources */
3478 /******************************<->*************************************
3480 * SaveWorkspaceResource (pWS, flags)
3484 * Modifies the RESOURCE_MANAGER property to add update versions
3485 * of the requested resources.
3489 * pWS = pointer to workspace data
3498 *************************************<->***********************************/
3500 SaveWorkspaceResources(
3501 WmWorkspaceData *pWS,
3502 unsigned long flags)
3504 char *buffer = NULL;
3505 int bufferLength = 0;
3510 char screenName[1024];
3511 char tmpScreenName[10];
3515 Dimension clientWidth;
3516 Dimension clientHeight;
3519 WmPanelistObject pPanelist = (WmPanelistObject) pWS->pSD->wPanelist;
3520 ClientData *pCD_Panel ;
3521 char tmpBuffer[MAXWMPATH+1];
3522 #endif /* PANELIST */
3525 /* allocate initial data space */
3526 if ((data = (char *) XtMalloc (MAXWMPATH+1)) == NULL)
3529 GETMESSAGE(76,12,"Insufficient memory to save resources")));
3530 Do_Quit_Mwm (False);
3535 if (bufferLength == 0)
3537 buffer = (char *) XtMalloc (MAXWMPATH+1);
3538 bufferLength = MAXWMPATH;
3542 /* Get our current resource class */
3546 res_class = WM_RESOURCE_CLASS;
3550 res_class = DT_WM_RESOURCE_CLASS;
3553 strcpy(screenName, "*");
3554 strcat(screenName,XtName (pWS->pSD->screenTopLevelW));
3556 /* construct and write out the resources specification */
3558 if (flags & WM_RES_BACKDROP_IMAGE)
3560 iLen = (strlen (res_class) + strlen (screenName) +
3561 strlen (pWS->name) + strlen (WmNbackdrop) +
3562 strlen (WmNimage) + strlen (pWS->backdrop.image) + 20);
3564 if (iLen > bufferLength)
3566 bufferLength += iLen;
3568 XtRealloc (buffer, bufferLength * sizeof(char));
3571 sprintf (buffer, "%s%s*%s*%s*%s: %s\n", res_class,
3572 screenName, pWS->name,
3573 WmNbackdrop, WmNimage, pWS->backdrop.image);
3575 AddStringToResourceData (buffer, &data, &cum_len);
3579 if (flags & WM_RES_WORKSPACE_TITLE)
3583 asciiName = WmXmStringToString (pWS->title);
3585 iLen = strlen (res_class) + strlen (screenName) +
3586 strlen (pWS->name) + strlen (WmNtitle) +
3587 strlen (asciiName) + 16;
3589 if (iLen > bufferLength)
3591 bufferLength += iLen;
3593 XtRealloc (buffer, bufferLength * sizeof(char));
3596 sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
3597 screenName, pWS->name,
3598 WmNtitle, asciiName);
3600 AddStringToResourceData (buffer, &data, &cum_len);
3605 if ((flags & WM_RES_INITIAL_WORKSPACE) &&
3606 (!wmGD.useStandardBehavior))
3608 iLen = strlen (res_class) + strlen (screenName) +
3609 strlen (WmNinitialWorkspace) + strlen (pWS->name) + 14;
3611 if (iLen > bufferLength)
3613 bufferLength += iLen;
3615 XtRealloc (buffer, bufferLength * sizeof(char));
3618 sprintf (buffer, "%s%s*%s: %s\n", res_class,
3620 WmNinitialWorkspace, pWS->name);
3622 AddStringToResourceData (buffer, &data, &cum_len);
3625 if ((flags & WM_RES_WORKSPACE_LIST) &&
3626 (!wmGD.useStandardBehavior))
3628 WmWorkspaceData *pWSi;
3632 pWSi = pWS->pSD->pWS;
3634 pchQname = (char *) _DtWmParseMakeQuotedString (
3635 (unsigned char *)pWSi->name);
3636 strcpy ((char *)wmGD.tmpBuffer, pchQname);
3641 for (i=1; i<pWS->pSD->numWorkspaces; i++, pWSi++)
3643 strcat ((char *)wmGD.tmpBuffer, " ");
3644 pchQname = (char *) _DtWmParseMakeQuotedString (
3645 (unsigned char *)pWSi->name);
3646 strcat ((char *)wmGD.tmpBuffer, pchQname);
3650 sprintf (buffer, "%s%s*%s: %s\n", res_class,
3652 WmNworkspaceList, wmGD.tmpBuffer);
3654 AddStringToResourceData (buffer, &data, &cum_len);
3657 if ((flags & WM_RES_WORKSPACE_COUNT) &&
3658 (!wmGD.useStandardBehavior))
3662 sprintf (pchNumWs, "%d", pWS->pSD->numWorkspaces);
3664 iLen = strlen (res_class) + strlen (screenName) +
3665 strlen (WmNworkspaceCount) + strlen (pchNumWs) + 14;
3667 if (iLen > bufferLength)
3669 bufferLength += iLen;
3671 XtRealloc (buffer, bufferLength * sizeof(char));
3674 sprintf (buffer, "%s%s*%s: %s\n", res_class,
3676 WmNworkspaceCount, pchNumWs);
3678 AddStringToResourceData (buffer, &data, &cum_len);
3682 if ((flags & WM_RES_FP_POSITION) &&
3683 (O_Shell(pPanelist)) &&
3684 (!wmGD.useStandardBehavior) &&
3685 (!XFindContext (DISPLAY, XtWindow(O_Shell(pPanelist)),
3686 wmGD.windowContextType,
3687 (XtPointer)&pCD_Panel)))
3689 Position midX, midY, tmpX, tmpY;
3690 Dimension screenWidth, screenHeight;
3692 clientX = pCD_Panel->clientX;
3693 clientY = pCD_Panel->clientY;
3696 * Determine quadrant that the front panel midpoint is
3697 * in and save front panel with appropriate gravity.
3700 /* find panel midpoint */
3702 midX = clientX+(pCD_Panel->clientWidth >> 1);
3703 midY = clientY+(pCD_Panel->clientHeight >> 1);
3705 /* get screen dimensions */
3707 screenWidth = XDisplayWidth (DISPLAY, pCD_Panel->pSD->screen);
3708 screenHeight = XDisplayHeight (DISPLAY, pCD_Panel->pSD->screen);
3711 * Determine midpoint quadrant and set up client geometry
3712 * relative to that corner. Adjust if positionIsFrame
3715 if (midX <= (Position) screenWidth/2)
3717 if(wmGD.positionIsFrame)
3719 clientX -= pCD_Panel->frameInfo.upperBorderWidth;
3723 if (midY <= (Position) screenHeight/2)
3726 if(wmGD.positionIsFrame)
3728 clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
3729 pCD_Panel->frameInfo.titleBarHeight);
3731 sprintf (tmpBuffer, "+%d+%d", clientX, clientY);
3736 clientY = screenHeight - clientY - pCD_Panel->clientHeight;
3737 if(wmGD.positionIsFrame)
3739 clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
3742 sprintf (tmpBuffer, "+%d-%d", clientX, clientY);
3747 clientX = screenWidth - clientX - pCD_Panel->clientWidth;
3748 if (wmGD.positionIsFrame)
3750 clientX -= pCD_Panel->frameInfo.lowerBorderWidth;
3754 if (midY <= (Position) screenHeight/2)
3757 if(wmGD.positionIsFrame)
3759 clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
3760 pCD_Panel->frameInfo.titleBarHeight);
3762 sprintf (tmpBuffer, "-%d+%d", clientX, clientY);
3767 clientY = screenHeight - clientY - pCD_Panel->clientHeight;
3768 if(wmGD.positionIsFrame)
3770 clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
3772 sprintf (tmpBuffer, "-%d-%d", clientX, clientY);
3776 iLen = strlen (res_class) + strlen (screenName) +
3777 strlen (XtName(O_Shell(pPanelist))) +
3778 strlen (WmNgeometry) + strlen (tmpBuffer) + 18;
3780 if (iLen > bufferLength)
3782 bufferLength += iLen;
3784 XtRealloc (buffer, bufferLength * sizeof(char));
3787 sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
3789 XtName (O_Shell(pPanelist)),
3790 WmNgeometry, tmpBuffer);
3792 AddStringToResourceData (buffer, &data, &cum_len);
3794 #endif /* PANELIST */
3796 if ((flags & WM_RES_ICONBOX_GEOMETRY) &&
3797 (!wmGD.useStandardBehavior))
3799 /* update iconbox geometry string */
3801 if (pWS->iconBoxGeometry)
3803 XtFree((char *) (pWS->iconBoxGeometry));
3804 pWS->iconBoxGeometry = NULL;
3807 clientWidth = (pWS->pIconBox->pCD_iconBox->clientWidth -
3808 pWS->pIconBox->pCD_iconBox->baseWidth) /
3809 pWS->pIconBox->pCD_iconBox->widthInc;
3811 clientHeight = (pWS->pIconBox->pCD_iconBox->clientHeight -
3812 pWS->pIconBox->pCD_iconBox->baseHeight) /
3813 pWS->pIconBox->pCD_iconBox->heightInc ;
3815 if(wmGD.positionIsFrame)
3817 CalculateGravityOffset (pWS->pIconBox->pCD_iconBox, &xoff, &yoff);
3818 clientX = pWS->pIconBox->pCD_iconBox->clientX - xoff;
3819 clientY = pWS->pIconBox->pCD_iconBox->clientY - yoff;
3823 clientX = pWS->pIconBox->pCD_iconBox->clientX;
3824 clientY = pWS->pIconBox->pCD_iconBox->clientY;
3827 sprintf (buffer, "%dx%d+%d+%d", clientWidth, clientHeight,
3830 pWS->iconBoxGeometry = strdup( buffer);
3832 iLen = strlen (res_class) + strlen (screenName) +
3833 strlen (pWS->name) + strlen (WmNiconBoxGeometry) +
3834 strlen (pWS->iconBoxGeometry) + 18;
3836 if (iLen > bufferLength)
3838 bufferLength += iLen;
3840 XtRealloc (buffer, bufferLength * sizeof(char));
3843 sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
3844 screenName, pWS->name,
3845 WmNiconBoxGeometry, pWS->iconBoxGeometry);
3847 AddStringToResourceData (buffer, &data, &cum_len);
3854 * Merge in the resource(s)
3856 _DtAddToResource (DISPLAY, data);
3865 } /* END OF FUNCTION SaveWorkspaceResources */
3868 /******************************<->*************************************
3870 * AddStringToResourceData (string, pdata, plen)
3874 * Adds a string to a growing buffer of strings.
3878 * string - string to add
3879 * pdata - pointer to data pointer
3880 * plen - number of bytes used in *pdata already
3884 * *pdata - data pointer (may be changed by XtRealloc)
3885 * *plen - number of bytes used in *pdata (old value plus length
3891 *************************************<->***********************************/
3893 AddStringToResourceData(
3898 if ((*pdata = (char *) XtRealloc(*pdata, *plen+strlen(string)+1)) == NULL)
3900 Warning (((char *)GETMESSAGE(76, 13, "Insufficient memory to save resources.")));
3901 Do_Quit_Mwm (False);
3904 strcat (*pdata, string);
3905 *plen += strlen(string);
3906 } /* END OF FUNCTION AddStringToResourceData */
3909 /*************************************<->*************************************
3911 * DuplicateWorkspaceName (pSD, name, num)
3916 * This function searches the first "num" workspace names to see if the
3917 * passed "name" duplicates any workspace name defined so far.
3922 * pSD = pointer to screen data
3923 * name = potential string name for workspace
3924 * num = number of workspaces to check against
3928 * Return = True if a dupicate was found
3933 *************************************<->***********************************/
3935 DuplicateWorkspaceName (WmScreenData *pSD, unsigned char *name, int num)
3938 Boolean duplicate = False;
3940 if (pSD && pSD->pWS)
3942 for (i = 0; (i < num) && !duplicate; i++)
3944 if (!strcmp (pSD->pWS[i].name, (char *)name))
3955 int PrintWorkspaceList (pSD)
3959 WmWorkspaceData *pWS;
3961 ClientData *pClients[500];
3965 fprintf (stderr, "Screen: %d\n", pSD->screen);
3967 for (i =0; i < pSD->numWorkspaces; i++)
3971 fprintf (stderr, "\nWorkspace %s contains: \n", pWS->name);
3973 for (j = 0; j < pWS->numClients; j++)
3975 pCD = pWS->ppClients[j];
3976 fprintf (stderr, "\t%s\n", pCD->clientName);
3979 for (k = 0; k < numSaved; k++)
3981 if (pCD == pClients[k])
3990 pClients[numSaved++] = pCD;
3995 for (i = 0; i < numSaved; i++)
3998 fprintf (stderr, "\nClient %s is in: \n", pCD->clientName);
3999 for (j = 0; j < pCD->numInhabited; j++)
4001 pWS = GetWorkspaceData (pCD->pSD, pCD->pWsList[j].wsID);
4002 fprintf (stderr, "\t%s\n", pWS->name);
4006 } /* END OF FUNCTION PrintWorkspaceList */
4009 /* DO NOT ADD ANYTHING AFTER THE FOLLOWING #ENDIF !!! */