3891 lines
81 KiB
C
3891 lines
81 KiB
C
/*
|
||
* CDE - Common Desktop Environment
|
||
*
|
||
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
||
*
|
||
* These libraries and programs are free software; you can
|
||
* redistribute them and/or modify them under the terms of the GNU
|
||
* Lesser General Public License as published by the Free Software
|
||
* Foundation; either version 2 of the License, or (at your option)
|
||
* any later version.
|
||
*
|
||
* These libraries and programs are distributed in the hope that
|
||
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
||
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
* PURPOSE. See the GNU Lesser General Public License for more
|
||
* details.
|
||
*
|
||
* You should have received a copy of the GNU Lesser General Public
|
||
* License along with these libraries and programs; if not, write
|
||
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
||
* Floor, Boston, MA 02110-1301 USA
|
||
*/
|
||
/*
|
||
* (c) Copyright 1987,1988,1989,1990,1992,1993,1994 HEWLETT-PACKARD COMPANY
|
||
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
||
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
||
* (c) Copyright 1993, 1994 Novell, Inc.
|
||
* ALL RIGHTS RESERVED
|
||
*/
|
||
|
||
/*
|
||
* Included Files:
|
||
*/
|
||
|
||
#include "WmGlobal.h"
|
||
#include "WmHelp.h"
|
||
#include "WmResNames.h"
|
||
#include "WmIPlace.h"
|
||
#include "WmInitWs.h"
|
||
#include <X11/Xutil.h>
|
||
#include "WmICCC.h"
|
||
#include <Xm/Xm.h>
|
||
#include <Xm/AtomMgr.h>
|
||
#include <Dt/DtP.h>
|
||
#include <Dt/WsmM.h>
|
||
#include <stdio.h>
|
||
#include "WmPanelP.h"
|
||
#include "WmIPC.h" /* must be after DtP.h */
|
||
#include "WmPresence.h"
|
||
|
||
/* local macros */
|
||
#ifndef MIN
|
||
#define MIN(a,b) ((a)<=(b)?(a):(b))
|
||
#endif
|
||
|
||
#ifndef MAX
|
||
#define MAX(a,b) ((a)>=(b)?(a):(b))
|
||
#endif
|
||
|
||
|
||
/* internally defined functions */
|
||
|
||
#include "WmWrkspace.h"
|
||
|
||
/******** Static Function Declarations ********/
|
||
|
||
static void InsureUniqueWorkspaceHints(
|
||
ClientData *pCD) ;
|
||
|
||
/******** End Static Function Declarations ********/
|
||
|
||
/* FindDtSessionMatch () put in WmResParse.h */
|
||
|
||
/* external functions */
|
||
#include "WmBackdrop.h"
|
||
#include "WmError.h"
|
||
#include "WmFunction.h"
|
||
#include "WmIDecor.h"
|
||
#include "WmIconBox.h"
|
||
#include "WmMenu.h"
|
||
#include "WmProperty.h"
|
||
#include "WmResParse.h"
|
||
#include "WmWinInfo.h"
|
||
#include "WmWinList.h"
|
||
#include "WmWinState.h"
|
||
#include "WmXSMP.h"
|
||
|
||
/*
|
||
* Global Variables:
|
||
*/
|
||
|
||
/* a dynamically allocated list of workspaces used
|
||
* by F_AddToAllWorkspaces
|
||
*/
|
||
static int numResIDs = 0;
|
||
static WorkspaceID *pResIDs = NULL;
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* ChangeToWorkspace (pNewWS)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function changes to a new workspace.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pNewWS = pointer to workspace data
|
||
*
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
ChangeToWorkspace(
|
||
WmWorkspaceData *pNewWS )
|
||
|
||
{
|
||
ClientData *pCD;
|
||
int i;
|
||
WmScreenData *pSD = pNewWS->pSD;
|
||
|
||
ClientData *pWsPCD;
|
||
Context wsContext = F_CONTEXT_NONE;
|
||
|
||
if (pNewWS == pSD->pActiveWS)
|
||
return; /* already there */
|
||
|
||
pSD->pLastWS = pSD->pActiveWS;
|
||
|
||
/*
|
||
* Go through client list of old workspace and hide windows
|
||
* that shouldn't appear in new workspace.
|
||
*/
|
||
|
||
if (pSD->presence.shellW &&
|
||
pSD->presence.onScreen &&
|
||
pSD->presence.contextForClient == F_CONTEXT_ICON)
|
||
{
|
||
pWsPCD = pSD->presence.pCDforClient;
|
||
wsContext = pSD->presence.contextForClient;
|
||
HidePresenceBox (pSD, False);
|
||
}
|
||
|
||
for (i = 0; i < pSD->pActiveWS->numClients; i++)
|
||
{
|
||
pCD = pSD->pActiveWS->ppClients[i];
|
||
if (!ClientInWorkspace (pNewWS, pCD))
|
||
{
|
||
SetClientWsIndex(pCD);
|
||
SetClientState (pCD, pCD->clientState | UNSEEN_STATE,
|
||
CurrentTime);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Hide active icon text label
|
||
*/
|
||
if ((pSD->iconDecoration & ICON_ACTIVE_LABEL_PART) &&
|
||
wmGD.activeIconTextDisplayed)
|
||
{
|
||
HideActiveIconText(pSD);
|
||
}
|
||
|
||
/*
|
||
* Unmap old icon box
|
||
*/
|
||
if (pSD->useIconBox)
|
||
{
|
||
UnmapIconBoxes (pSD->pLastWS);
|
||
}
|
||
|
||
/*
|
||
* Set new active workspace
|
||
*/
|
||
pSD->pActiveWS = pNewWS;
|
||
ChangeBackdrop (pNewWS);
|
||
|
||
/*
|
||
* Go through client list of new workspace and show windows
|
||
* that should appear.
|
||
*/
|
||
for (i = 0; i < pNewWS->numClients; i++)
|
||
{
|
||
pCD = pNewWS->ppClients[i];
|
||
SetClientWsIndex(pCD);
|
||
if (pCD->clientState & UNSEEN_STATE)
|
||
{
|
||
SetClientState (pCD,
|
||
(pCD->clientState & ~UNSEEN_STATE), CurrentTime);
|
||
}
|
||
if ((pCD->clientState == MINIMIZED_STATE) &&
|
||
((!pCD->pSD->useIconBox) ||
|
||
(!P_ICON_BOX(pCD))))
|
||
{
|
||
XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
|
||
ICON_X(pCD), ICON_Y(pCD));
|
||
}
|
||
|
||
if (pCD->iconWindow)
|
||
{
|
||
unsigned int xOffset, yOffset;
|
||
|
||
/*
|
||
* Adjust for icons in the box
|
||
*/
|
||
|
||
if (pNewWS->pIconBox)
|
||
{
|
||
xOffset = IB_MARGIN_WIDTH;
|
||
yOffset = IB_MARGIN_HEIGHT;
|
||
}
|
||
else
|
||
{
|
||
xOffset = 0;
|
||
yOffset = 0;
|
||
}
|
||
|
||
/*
|
||
* reparent icon window to frame in this workspace
|
||
*/
|
||
if ((ICON_DECORATION(pCD) & ICON_IMAGE_PART) &&
|
||
(pCD->iconWindow))
|
||
{
|
||
ReparentIconWindow (pCD, xOffset, yOffset);
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( (wsContext == F_CONTEXT_ICON &&
|
||
ClientInWorkspace (ACTIVE_WS, pWsPCD)) ||
|
||
|
||
(pSD->presence.shellW &&
|
||
! pSD->presence.userDismissed &&
|
||
ClientInWorkspace (ACTIVE_WS, pSD->presence.pCDforClient) &&
|
||
pSD->presence.contextForClient == F_CONTEXT_ICON))
|
||
{
|
||
ShowPresenceBox(pSD->presence.pCDforClient, F_CONTEXT_ICON);
|
||
}
|
||
|
||
SetCurrentWorkspaceProperty (pSD);
|
||
|
||
/* send workspace change broadcast message */
|
||
dtSendWorkspaceModifyNotification(pSD, (Atom) pNewWS->id,
|
||
DtWSM_REASON_CURRENT);
|
||
|
||
} /* END OF FUNCTION ChangeToWorkspace */
|
||
|
||
/******************************<->*************************************
|
||
*
|
||
* ChangeWorkspaceTitle (pWS, pchTitle)
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Set the title for a workspace.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pWS = pointer to workspace data
|
||
* pchTitle = new title to assign to this workspace
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* none
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*
|
||
******************************<->***********************************/
|
||
|
||
void
|
||
ChangeWorkspaceTitle(
|
||
WmWorkspaceData *pWS,
|
||
char * pchTitle)
|
||
{
|
||
XmString xmstr;
|
||
|
||
/*
|
||
* Convert string to XmString
|
||
*/
|
||
xmstr = XmStringCreateLocalized (pchTitle);
|
||
|
||
/*
|
||
* Validate title ?
|
||
*/
|
||
|
||
/*
|
||
* Replace title in workspace data
|
||
*/
|
||
XmStringFree (pWS->title);
|
||
pWS->title = xmstr;
|
||
|
||
/*
|
||
* Save changes to resource database
|
||
*/
|
||
SaveWorkspaceResources (pWS, (WM_RES_WORKSPACE_TITLE));
|
||
|
||
/*
|
||
* Replace old workspace in info property
|
||
*/
|
||
SetWorkspaceInfoProperty (pWS);
|
||
XFlush (DISPLAY);
|
||
|
||
/*
|
||
* Inform the world of the new workspace title
|
||
*/
|
||
dtSendWorkspaceModifyNotification(pWS->pSD, pWS->id, DtWSM_REASON_TITLE);
|
||
|
||
} /* END OF FUNCTION ChangeWorkspaceTitle */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* UpdateWorkspacePresenceProperty (pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function updates the _DT_WORKSPACE_PRESENCE property for a
|
||
* client window
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
UpdateWorkspacePresenceProperty(
|
||
ClientData *pCD )
|
||
|
||
{
|
||
static Atom *pPresence = NULL;
|
||
static unsigned long cPresence = 0;
|
||
unsigned long i;
|
||
|
||
if (wmGD.useStandardBehavior)
|
||
{
|
||
/*
|
||
* Don't change any workspace properties in standard behavior
|
||
* mode.
|
||
*/
|
||
return;
|
||
}
|
||
|
||
if (!pPresence)
|
||
{
|
||
/* allocate initial list */
|
||
if (!(pPresence = (Atom *)
|
||
XtMalloc (pCD->pSD->numWorkspaces * sizeof(Atom))))
|
||
{
|
||
Warning (((char *)GETMESSAGE(76, 1, "Insufficient memory for workspace presence property")));
|
||
}
|
||
else
|
||
{
|
||
cPresence = pCD->pSD->numWorkspaces;
|
||
}
|
||
}
|
||
|
||
if (cPresence < pCD->numInhabited)
|
||
{
|
||
/* allocate bigger list */
|
||
if (!(pPresence = (Atom *)
|
||
XtRealloc ((char *)pPresence, pCD->numInhabited * sizeof(Atom))))
|
||
{
|
||
Warning (((char *)GETMESSAGE(76, 2, "Insufficient memory for workspace presence property")));
|
||
}
|
||
else
|
||
{
|
||
cPresence = pCD->numInhabited;
|
||
}
|
||
}
|
||
|
||
for (i = 0; (i < pCD->numInhabited) && (i < cPresence) ; i++)
|
||
{
|
||
pPresence[i] = pCD->pWsList[i].wsID;
|
||
}
|
||
|
||
SetWorkspacePresence (pCD->client, pPresence,
|
||
MIN(pCD->numInhabited, cPresence));
|
||
|
||
} /* END OF FUNCTION UpdateWorkspacePresenceProperty */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* AddPersistentWindow (pWS)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function adds windows that want to be in all workspaces to
|
||
* the workspace passed in.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pWS = pointer to workspace data
|
||
*
|
||
* Outputs:
|
||
* --------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
AddPersistentWindows(
|
||
WmWorkspaceData *pWS)
|
||
|
||
{
|
||
WmScreenData *pSD = pWS->pSD;
|
||
int i;
|
||
ClientListEntry *pCLE;
|
||
|
||
/*
|
||
* For all the windows managed for this screen, see if they
|
||
* want to be in all workspaces and add them to this workspace.
|
||
*/
|
||
pCLE = pSD->clientList;
|
||
|
||
while (1)
|
||
{
|
||
/*
|
||
* Process all the non-icon client list entries
|
||
*/
|
||
if ((pCLE->type == NORMAL_STATE) &&
|
||
(pCLE->pCD->putInAll))
|
||
{
|
||
AddClientToWorkspaces( pCLE->pCD, &(pWS->id), 1 );
|
||
}
|
||
|
||
/*
|
||
* Test for exit condition and advance client list pointer
|
||
*/
|
||
if (pCLE == pSD->lastClient)
|
||
break;
|
||
else
|
||
pCLE = pCLE->nextSibling;
|
||
}
|
||
|
||
} /* END OF FUNCTION AddPersistentWindows */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* CreateWorkspace (pSD, pchTitle)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function creates a new workspace.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pSD = pointer to screen data
|
||
* pchTitle = user-visible title for the workspace (may be NULL)
|
||
*
|
||
* Outputs:
|
||
* --------
|
||
* Returns pointer to workspace data if successful.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
WmWorkspaceData *
|
||
CreateWorkspace(
|
||
WmScreenData *pSD,
|
||
unsigned char *pchTitle )
|
||
|
||
{
|
||
WmWorkspaceData *pWS = NULL;
|
||
String string;
|
||
int iActiveWS;
|
||
|
||
/*
|
||
* Allocate more workspace datas if we have no spares
|
||
*/
|
||
if (pSD->numWsDataAllocated <= pSD->numWorkspaces)
|
||
{
|
||
iActiveWS = (pSD->pActiveWS - pSD->pWS) / sizeof (WmWorkspaceData);
|
||
pSD->numWsDataAllocated += WS_ALLOC_AMOUNT;
|
||
pSD->pWS = (WmWorkspaceData *) XtRealloc ((char *)pSD->pWS,
|
||
pSD->numWsDataAllocated * sizeof(WmWorkspaceData));
|
||
pSD->pActiveWS = &(pSD->pWS[iActiveWS]);
|
||
}
|
||
|
||
/*
|
||
* Give this workspace a name
|
||
*/
|
||
pWS = &pSD->pWS[pSD->numWorkspaces];
|
||
string = (String) GenerateWorkspaceName (pSD, pSD->numWorkspaces);
|
||
pWS->name = XtNewString (string);
|
||
|
||
/*
|
||
* Initialize the workspace data structure
|
||
*/
|
||
InitWmWorkspace (pWS, pSD);
|
||
if (pchTitle)
|
||
{
|
||
if (pWS->title)
|
||
XmStringFree (pWS->title);
|
||
pWS->title = XmStringCreateLocalized ((char *)pchTitle);
|
||
}
|
||
|
||
/*
|
||
* bump workspace count
|
||
*/
|
||
pSD->numWorkspaces++;
|
||
|
||
/*
|
||
* update the properties that announce workspace info
|
||
*/
|
||
SetWorkspaceInfoProperty (pWS);
|
||
SetWorkspaceListProperty (pSD);
|
||
|
||
SaveWorkspaceResources(pWS, (WM_RES_WORKSPACE_LIST |
|
||
WM_RES_WORKSPACE_COUNT |
|
||
WM_RES_WORKSPACE_TITLE));
|
||
dtSendWorkspaceModifyNotification(pSD, pWS->id, DtWSM_REASON_ADD);
|
||
|
||
/*
|
||
* Insure there's an iconbox for this workspace
|
||
*/
|
||
if (pSD->useIconBox)
|
||
{
|
||
AddIconBoxForWorkspace (pWS);
|
||
}
|
||
|
||
/*
|
||
* Add windows to this workspaces that want to be in "all"
|
||
* workspaces.
|
||
*/
|
||
AddPersistentWindows (pWS);
|
||
|
||
/*
|
||
* Update workspace presence dialog data
|
||
*/
|
||
UpdatePresenceWorkspaces(pSD);
|
||
|
||
return (pWS);
|
||
} /* END OF FUNCTION CreateWorkspace */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* DeleteWorkspace (pWS)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function deletes a workspace.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pWS = pointer to screen data
|
||
*
|
||
* Outputs:
|
||
* --------
|
||
* Returns pointer to workspace data if successful.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
DeleteWorkspace(
|
||
WmWorkspaceData *pWS )
|
||
|
||
{
|
||
WmWorkspaceData *pWSdest; /* destination WS */
|
||
int i, iNextWs;
|
||
ClientData *pCD;
|
||
WmScreenData *pSD = pWS->pSD;
|
||
Atom aOldId;
|
||
|
||
if (pSD->numWorkspaces > 1)
|
||
{
|
||
/*
|
||
* Find index for "next" workspace
|
||
*/
|
||
for (iNextWs = 0; iNextWs < pSD->numWorkspaces; iNextWs++)
|
||
{
|
||
if (pSD->pWS[iNextWs].id == pWS->id)
|
||
{
|
||
iNextWs++;
|
||
break;
|
||
}
|
||
}
|
||
|
||
/* check bounds and wrap */
|
||
if (iNextWs >= pSD->numWorkspaces)
|
||
iNextWs = 0;
|
||
|
||
/*
|
||
* Determine default destination for clients that exist
|
||
* only in the workspace being deleted.
|
||
*/
|
||
if (pWS == ACTIVE_WS)
|
||
{
|
||
pWSdest = &(pSD->pWS[iNextWs]);
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* Use the "current" workspace as the default destination
|
||
*/
|
||
pWSdest = ACTIVE_WS;
|
||
}
|
||
|
||
/*
|
||
* Move all clients out of this workspace
|
||
*/
|
||
while (pWS->numClients > 0)
|
||
{
|
||
/* repeatedly remove the first one until all are gone */
|
||
pCD = pWS->ppClients[0];
|
||
|
||
|
||
if (pCD->numInhabited == 1)
|
||
{
|
||
if (!(pCD->clientFlags & (ICON_BOX)))
|
||
{
|
||
AddClientToWorkspaces (pCD, &(pWSdest->id), 1);
|
||
}
|
||
}
|
||
|
||
RemoveClientFromWorkspaces (pCD, &(pWS->id), 1);
|
||
}
|
||
|
||
/*
|
||
* If we're deleting the current workspace,
|
||
* then change to another workspace.
|
||
*/
|
||
if (pWS == ACTIVE_WS)
|
||
{
|
||
ChangeToWorkspace (pWSdest);
|
||
}
|
||
|
||
/*
|
||
* Save the workspace ID for the notification message.
|
||
*/
|
||
aOldId = pWS->id;
|
||
|
||
/*
|
||
* Destroy the icon box for the workspace if one was used
|
||
*/
|
||
if (pSD->useIconBox)
|
||
{
|
||
DestroyIconBox (pWS);
|
||
}
|
||
|
||
/*
|
||
* Delete the property containing information on this workspace
|
||
*/
|
||
DeleteWorkspaceInfoProperty (pWS);
|
||
|
||
/*
|
||
* Delete the workspace data structures
|
||
*/
|
||
if (pWS->backdrop.imagePixmap)
|
||
{
|
||
if (!XmDestroyPixmap (XtScreen(pWS->workspaceTopLevelW),
|
||
pWS->backdrop.imagePixmap))
|
||
{
|
||
/* not in Xm pixmap cache */
|
||
}
|
||
}
|
||
|
||
/* free pWS->backdrop.image */
|
||
if ((pWS->backdrop.flags & BACKDROP_IMAGE_ALLOCED) &&
|
||
(pWS->backdrop.image))
|
||
{
|
||
free (pWS->backdrop.image);
|
||
}
|
||
|
||
/*
|
||
* Free up icon placement data
|
||
*/
|
||
if (wmGD.iconAutoPlace)
|
||
{
|
||
if (pWS->IPData.placeList != NULL)
|
||
XtFree ((char *) pWS->IPData.placeList);
|
||
if (pWS->IPData.placementRowY != NULL)
|
||
XtFree ((char *) pWS->IPData.placementRowY);
|
||
if (pWS->IPData.placementColX != NULL)
|
||
XtFree ((char *) pWS->IPData.placementColX);
|
||
}
|
||
|
||
XtFree ((char *) pWS->name);
|
||
XmStringFree (pWS->title);
|
||
XtFree ((char *) pWS->ppClients);
|
||
if (pWS->iconBoxGeometry) XtFree ((char *) pWS->iconBoxGeometry);
|
||
XtDestroyWidget (pWS->workspaceTopLevelW);
|
||
|
||
/*
|
||
* Compress the list of workspaces if we're not deleting
|
||
* the last one. (Do piece-wise to avoid overlapping copy
|
||
* problems).
|
||
*/
|
||
if (iNextWs > 0)
|
||
{
|
||
WmWorkspaceData *pWSdest;
|
||
WmWorkspaceData *pWSsrc;
|
||
int j;
|
||
|
||
pWSdest = pWS;
|
||
pWSsrc = &(pSD->pWS[iNextWs]);
|
||
|
||
for (j=iNextWs; j < pSD->numWorkspaces; j++)
|
||
{
|
||
memcpy (pWSdest, pWSsrc, sizeof(WmWorkspaceData));
|
||
if (pSD->pActiveWS == pWSsrc)
|
||
{
|
||
pSD->pActiveWS = pWSdest;
|
||
}
|
||
pWSdest++;
|
||
pWSsrc++;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* We now have one less workspace.
|
||
*/
|
||
pSD->numWorkspaces--;
|
||
|
||
/*
|
||
* Update the properties that announce workspace info.
|
||
*/
|
||
SetWorkspaceListProperty (pSD);
|
||
|
||
SaveWorkspaceResources(pWSdest,
|
||
(WM_RES_WORKSPACE_LIST | WM_RES_WORKSPACE_COUNT));
|
||
|
||
dtSendWorkspaceModifyNotification(pSD, aOldId, DtWSM_REASON_DELETE);
|
||
|
||
/*
|
||
* Update workspace presence dialog data
|
||
*/
|
||
UpdatePresenceWorkspaces(pSD);
|
||
}
|
||
} /* END OF FUNCTION DeleteWorkspace */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* ProcessDtWmHints (pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Process the _DT_WM_HINTS property on the window (if any).
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* pCD = may be changed.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
ProcessDtWmHints (ClientData *pCD)
|
||
{
|
||
DtWmHints *pHints;
|
||
Atom property;
|
||
long saveFunctions;
|
||
|
||
/*
|
||
* Retrieve the _DT_WM_HINTS property if it exists.
|
||
*/
|
||
|
||
property = XmInternAtom(DISPLAY, _XA_DT_WM_HINTS, False);
|
||
|
||
if (
|
||
(HasProperty (pCD, property))
|
||
&& (_DtWsmGetDtWmHints (DISPLAY, pCD->client, &pHints) == Success))
|
||
{
|
||
pCD->clientFlags |= GOT_DT_WM_HINTS;
|
||
if (pHints->flags & DtWM_HINTS_FUNCTIONS)
|
||
{
|
||
if (pHints->functions & DtWM_FUNCTION_ALL)
|
||
{
|
||
/* client indicating inapplicable functions */
|
||
pCD->dtwmFunctions &= ~(pHints->functions);
|
||
}
|
||
else
|
||
{
|
||
/* client indicating applicable functions */
|
||
pCD->dtwmFunctions &= pHints->functions;
|
||
}
|
||
}
|
||
|
||
if (pHints->flags & DtWM_HINTS_BEHAVIORS)
|
||
{
|
||
/* set applicable behaviors */
|
||
pCD->dtwmBehaviors = pHints->behaviors;
|
||
if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
|
||
{
|
||
/*
|
||
* if this is a restored subpanel, remove the
|
||
* DtWM_BEHAVIOR_SUB_RESTORED bit so the next
|
||
* time through the subpanel will behave as an
|
||
* existing subpanel
|
||
*/
|
||
pHints->behaviors &= ~DtWM_BEHAVIOR_SUB_RESTORED;
|
||
_DtWsmSetDtWmHints (DISPLAY, pCD->client, pHints);
|
||
}
|
||
}
|
||
|
||
XFree ((char*)pHints);
|
||
}
|
||
|
||
if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_PANEL)
|
||
{
|
||
/* put it in all workspaces */
|
||
saveFunctions = pCD->dtwmFunctions;
|
||
pCD->dtwmFunctions |= DtWM_FUNCTION_OCCUPY_WS;
|
||
|
||
F_AddToAllWorkspaces (NULL, pCD, NULL);
|
||
|
||
pCD->dtwmFunctions = saveFunctions;
|
||
pCD->clientFlags |= FRONT_PANEL_BOX ;
|
||
}
|
||
} /* END OF ProcessDtWmHints */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* GetClientWorkspaceInfo (pCD, manageFlags);
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function sets up the portion of client data that has to
|
||
* do with workspaces
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data (only partly initialized!!)
|
||
* manageFlags = tells us, in particular, if we're restarting.
|
||
*
|
||
* Outputs:
|
||
* --------
|
||
* pCD = updated client data
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
GetClientWorkspaceInfo(
|
||
ClientData *pCD,
|
||
long manageFlags )
|
||
|
||
{
|
||
Atom *pIDs;
|
||
int i;
|
||
unsigned int numIDs = 0;
|
||
Boolean bAll;
|
||
|
||
/*
|
||
* Allocate initial workspace ID list
|
||
* fill with NULL IDs
|
||
*/
|
||
if ((pCD->pWsList = (WsClientData *)
|
||
XtMalloc(pCD->pSD->numWorkspaces * sizeof(WsClientData))) == NULL)
|
||
{
|
||
Warning (((char *)GETMESSAGE(76, 4, "Insufficient memory for client data")));
|
||
return (False);
|
||
}
|
||
pCD->currentWsc = 0;
|
||
pCD->pWorkspaceHints = NULL;
|
||
pCD->sizeWsList = pCD->pSD->numWorkspaces;
|
||
pCD->numInhabited = 0; /* no valid ones yet */
|
||
for (i = 0; i < pCD->pSD->numWorkspaces; i++)
|
||
{
|
||
pCD->pWsList[i].wsID = None;
|
||
pCD->pWsList[i].iconPlace = NO_ICON_PLACE;
|
||
pCD->pWsList[i].iconX = 0;
|
||
pCD->pWsList[i].iconY = 0;
|
||
pCD->pWsList[i].iconFrameWin = None;
|
||
pCD->pWsList[i].pIconBox = NULL;
|
||
}
|
||
pCD->putInAll = bAll = False;
|
||
|
||
/*
|
||
* Determine initial workspace set.
|
||
*
|
||
* If this is a secondary window, use the hints from the
|
||
* transient tree leader.
|
||
*
|
||
* Else if we're restarting, then use our own workspace presence.
|
||
*
|
||
* Else if a command line option is specified, use that.
|
||
*
|
||
* Else, if workspace hints are on the window, then use them.
|
||
*
|
||
* If none of the above work out, the window will be put into
|
||
* the current workspace.
|
||
*/
|
||
if (pCD->client &&
|
||
((pCD->transientLeader && GetLeaderPresence(pCD, &pIDs, &numIDs)) ||
|
||
((manageFlags & MANAGEW_WM_RESTART) &&
|
||
GetMyOwnPresence (pCD, &pIDs, &numIDs)) ||
|
||
(WorkspaceIsInCommand (DISPLAY, pCD, &pIDs, &numIDs)) ||
|
||
(
|
||
HasProperty (pCD, wmGD.xa_DT_WORKSPACE_HINTS)
|
||
&& (GetWorkspaceHints (DISPLAY, pCD->client, &pIDs, &numIDs, &bAll) ==
|
||
Success))) &&
|
||
numIDs)
|
||
{
|
||
/*
|
||
* Got some workspace hints!
|
||
*/
|
||
pCD->putInAll = bAll;
|
||
ProcessWorkspaceHintList (pCD, pIDs, numIDs);
|
||
}
|
||
|
||
if (pCD->numInhabited == 0)
|
||
{
|
||
/*
|
||
* If not in any workspaces, then put the client into
|
||
* the current one.
|
||
*/
|
||
PutClientIntoWorkspace (pCD->pSD->pActiveWS, pCD);
|
||
}
|
||
|
||
return (True);
|
||
|
||
} /* END OF FUNCTION GetClientWorkspaceInfo */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* WorkspaceIsInCommand (dpy, pCD, ppIDs, pNumIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Determine if workspace specification is in command line for client
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* dpy - pointer to display structure
|
||
* pCD - ptr to client data
|
||
* ppIDs - pointer for returning list of IDs
|
||
* pNumIDs - number of IDs being returned
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* ppIDs - returned list of IDs
|
||
* pNumIDs - number of IDs being returned
|
||
*
|
||
* Return - True if workspace option found, false otherwise
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
* Malloc's memory that must be freed
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
WorkspaceIsInCommand(
|
||
Display *dpy,
|
||
ClientData *pCD,
|
||
WorkspaceID **ppIDs,
|
||
unsigned int *pNumIDs )
|
||
{
|
||
int wmcArgc;
|
||
char **wmcArgv = NULL;
|
||
Boolean rval = False;
|
||
unsigned char *pch = NULL;
|
||
XTextProperty clientMachineProp;
|
||
|
||
if (FindClientDBMatch(pCD, (char **)&pch))
|
||
{
|
||
if (pch)
|
||
{
|
||
if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
|
||
{
|
||
rval = True;
|
||
}
|
||
XtFree((char *)pch);
|
||
}
|
||
}
|
||
else if (HasProperty (pCD, XA_WM_COMMAND) &&
|
||
XGetCommand (dpy, pCD->client, &wmcArgv, &wmcArgc) &&
|
||
(wmcArgv != NULL))
|
||
{
|
||
if (pCD->pSD->remainingSessionItems)
|
||
{
|
||
if(!(XGetWMClientMachine(dpy, pCD->client, &clientMachineProp)))
|
||
{
|
||
clientMachineProp.value = NULL;
|
||
}
|
||
if (FindDtSessionMatch(wmcArgc, wmcArgv, pCD, pCD->pSD,
|
||
(char **)&pch,
|
||
(char *)clientMachineProp.value))
|
||
{
|
||
/*
|
||
* If we found a match to a client description
|
||
* in the DtSessionHints, use the information from
|
||
* the Hints instead of the command line
|
||
*/
|
||
if (pch)
|
||
{
|
||
if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
|
||
{
|
||
rval = True;
|
||
}
|
||
/*
|
||
* free malloced memory containing workspace list
|
||
*/
|
||
XtFree ((char *)pch);
|
||
}
|
||
|
||
}
|
||
if (clientMachineProp.value)
|
||
{
|
||
XFree ((char*)clientMachineProp.value);
|
||
}
|
||
}
|
||
|
||
if (!rval && FindWsNameInCommand (wmcArgc, wmcArgv, &pch))
|
||
{
|
||
if (ConvertNamesToIDs (pCD->pSD, pch, ppIDs, pNumIDs))
|
||
{
|
||
rval = True;
|
||
}
|
||
}
|
||
|
||
if (wmcArgv != NULL)
|
||
{
|
||
XFreeStringList (wmcArgv);
|
||
}
|
||
}
|
||
|
||
return (rval);
|
||
} /* END OF FUNCTION WorkspaceIsInCommand */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* ConvertNamesToIDs (pSD, pch, ppAtoms, pNumAtoms)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Takes a string containing a list of names separated by white space
|
||
* and converts it to a list of workspace IDs.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pSD - pointer to screen data
|
||
* pchIn - pointer to original string
|
||
* ppAtoms - pointer to an atom pointer (for returning list pointer)
|
||
* pNumAtoms - pointer to the number of atoms being returned.
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* *ppAtoms - points to a list of atoms returned.
|
||
* *pNumAtoms - the number of atoms being returned.
|
||
*
|
||
* Return - True if some Atoms are being returned
|
||
*
|
||
* Comments:
|
||
* --------
|
||
* Processes local copy of string so that pch is not modified.
|
||
*
|
||
* The list of atoms returned has been dynamically allocated.
|
||
* Please XtFree() it when you're done.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
ConvertNamesToIDs(
|
||
WmScreenData *pSD,
|
||
unsigned char *pchIn,
|
||
WorkspaceID **ppAtoms,
|
||
unsigned int *pNumAtoms )
|
||
|
||
{
|
||
unsigned char *pchLocal, *pch, *pchName;
|
||
int num = 0;
|
||
int numLocalIDs;
|
||
WorkspaceID *pLocalIDs;
|
||
|
||
if ((pLocalIDs = (WorkspaceID *) XtMalloc (WS_ALLOC_AMOUNT *
|
||
sizeof(WorkspaceID))) == NULL)
|
||
{
|
||
Warning (((char *)GETMESSAGE(76, 5, "Insufficient Memory (ConvertNamesToIDs)")));
|
||
ExitWM (WM_ERROR_EXIT_VALUE);
|
||
}
|
||
numLocalIDs = WS_ALLOC_AMOUNT;
|
||
|
||
if (pchIn && (pchLocal = (unsigned char *) XtMalloc(1+strlen((char *)pchIn))))
|
||
{
|
||
strcpy ((char *)pchLocal, (char *)pchIn);
|
||
pch = pchLocal;
|
||
|
||
while ((pchName = GetSmartString (&pch)))
|
||
{
|
||
int iwsx;
|
||
XmString xms;
|
||
|
||
/*
|
||
* Check workspace for workspace titles; map to
|
||
* workspace names.
|
||
*/
|
||
xms = XmStringCreateLocalized ((char *)pchName);
|
||
for (iwsx = 0; iwsx < pSD->numWorkspaces; iwsx++)
|
||
{
|
||
if (XmStringCompare (xms, pSD->pWS[iwsx].title))
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
XmStringFree (xms);
|
||
|
||
if (iwsx < pSD->numWorkspaces)
|
||
{
|
||
/*
|
||
* Found a workspace title we've got,
|
||
* use id for workspace name
|
||
*/
|
||
pLocalIDs[num] = pSD->pWS[iwsx].id;
|
||
num++;
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* Try for match on workspace name
|
||
*/
|
||
pLocalIDs[num] = (WorkspaceID)
|
||
XInternAtom (DISPLAY, (char *)pchName, False);
|
||
num++;
|
||
}
|
||
|
||
if (num >= numLocalIDs)
|
||
{
|
||
/* list too small */
|
||
numLocalIDs += WS_ALLOC_AMOUNT;
|
||
if ((pLocalIDs = (WorkspaceID *) XtRealloc ((char *)pLocalIDs,
|
||
numLocalIDs * sizeof(WorkspaceID))) == NULL)
|
||
{
|
||
Warning (((char *)GETMESSAGE(76, 6, "Insufficient Memory (ConvertNamesToIDs)")));
|
||
ExitWM (WM_ERROR_EXIT_VALUE);
|
||
}
|
||
}
|
||
}
|
||
|
||
XtFree ((char *)pchLocal);
|
||
}
|
||
|
||
*ppAtoms = pLocalIDs;
|
||
*pNumAtoms = num;
|
||
return (num != 0);
|
||
|
||
} /* END OF FUNCTION ConvertNamesToIDs */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* CheckForPutInAllRequest (pCD, pIDs, numIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Tests for the presence of the "all" atom in the atom list
|
||
* and sets the "putInAll" flag on the client.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD - pointer to client data
|
||
* pIDs - pointer to ID list
|
||
* numIDs - number of IDs in list
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* pCD - putInAll member may be set
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
CheckForPutInAllRequest(
|
||
ClientData *pCD,
|
||
Atom *pIDs,
|
||
unsigned int numIDs )
|
||
|
||
{
|
||
unsigned int i;
|
||
|
||
for (i = 0; (i < numIDs) && !(pCD->putInAll); i++)
|
||
{
|
||
if (pIDs[i] == wmGD.xa_ALL_WORKSPACES)
|
||
{
|
||
pCD->putInAll = True;
|
||
break;
|
||
}
|
||
}
|
||
|
||
} /* END OF FUNCTION CheckForPutInAllRequest */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* FindWsNameInCommand (argc, argv, ppch)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Finds and returns the workspace name option in the command line
|
||
* (if any)
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* argc - argument count
|
||
* argv - argument list
|
||
* ppch - string pointer to return
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* *ppch - points to ws name (if found)
|
||
*
|
||
* Return - True if wsname found
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
FindWsNameInCommand(
|
||
int argc,
|
||
char *argv[],
|
||
unsigned char **ppch )
|
||
|
||
{
|
||
|
||
#define XRM_OPT "-xrm"
|
||
#define WSLIST "*workspaceList:"
|
||
#define WSLIST_LEN 14
|
||
|
||
int i = 1;
|
||
Boolean rval = False;
|
||
unsigned char *pch, *pchTmp, *pch0;
|
||
unsigned char *pchRes, *pchValue;
|
||
|
||
if (argc > 0)
|
||
{
|
||
while (--argc && !rval)
|
||
{
|
||
if (!strcmp(argv[i], XRM_OPT) && (argc > 1))
|
||
{
|
||
/*
|
||
* found "-xrm", now look at resource spec
|
||
*/
|
||
pch0 = (unsigned char *) strdup (argv[i+1]);
|
||
if (!pch0)
|
||
{
|
||
Warning (((char *)GETMESSAGE(76, 7, "Insufficient memory")));
|
||
ExitWM (WM_ERROR_EXIT_VALUE);
|
||
}
|
||
pch = pch0;
|
||
|
||
/* strip off quotes ,
|
||
* separate two halve of resource spec
|
||
*/
|
||
pchRes = GetSmartString (&pch);
|
||
pchValue = pch;
|
||
|
||
if ((*pchRes) && (*pch))
|
||
{
|
||
/* Erase colon at end of resource name */
|
||
|
||
pch = (unsigned char *) strrchr((char *)pchRes, ':');
|
||
if (pch)
|
||
{
|
||
*pch = '\0';
|
||
}
|
||
|
||
/* find beginning of last component of resource
|
||
* spec
|
||
*/
|
||
pch = (unsigned char *) strrchr ((char *)pchRes, '*');
|
||
pchTmp = (unsigned char *) strrchr ((char *)pchRes, '.');
|
||
if (pchTmp > pch)
|
||
{
|
||
pch = pchTmp;
|
||
}
|
||
|
||
if (pch && *pch && *(pch+1))
|
||
{
|
||
pch += 1;
|
||
}
|
||
|
||
/* compare resource with our resource */
|
||
|
||
if ( (!strcmp ((char *)pch, WmNworkspaceList)) ||
|
||
(!strcmp ((char *)pch, WmCWorkspaceList)))
|
||
{
|
||
/* match, compute return position in
|
||
passed in string */
|
||
|
||
*ppch = (unsigned char *)
|
||
(argv[i+1] + (pchValue - pch0));
|
||
rval = True;
|
||
XtFree ((char *)pch0);
|
||
pch0 = NULL;
|
||
}
|
||
}
|
||
|
||
i++; /* skip next arg */
|
||
argc--;
|
||
|
||
if (pch0)
|
||
{
|
||
XtFree ((char *)pch0);
|
||
}
|
||
}
|
||
i++;
|
||
}
|
||
}
|
||
return (rval);
|
||
} /* END OF FUNCTION FindWsNameInCommand */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* PutClientIntoWorkspace (pWS, pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function updates the data for the client and workspace to
|
||
* reflect the presence of the client in the workspace.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pWS = pointer to workspace data
|
||
* pCD = pointer to client data
|
||
*
|
||
* Outputs:
|
||
* --------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
PutClientIntoWorkspace(
|
||
WmWorkspaceData *pWS,
|
||
ClientData *pCD )
|
||
|
||
{
|
||
int i = pCD->numInhabited;
|
||
int iAdded, j, k;
|
||
|
||
/* insure the client's got enough workspace data */
|
||
if (pCD->sizeWsList < pCD->pSD->numWorkspaces)
|
||
{
|
||
iAdded = pCD->pSD->numWorkspaces - pCD->sizeWsList;
|
||
|
||
pCD->sizeWsList = pCD->pSD->numWorkspaces;
|
||
pCD->pWsList = (WsClientData *)
|
||
XtRealloc((char *)pCD->pWsList,
|
||
(pCD->pSD->numWorkspaces * sizeof(WsClientData)));
|
||
|
||
/* intialized new data */
|
||
j = pCD->sizeWsList - 1;
|
||
for (j=1; j <= iAdded; j++)
|
||
{
|
||
k = pCD->sizeWsList - j;
|
||
pCD->pWsList[k].iconPlace = NO_ICON_PLACE;
|
||
pCD->pWsList[k].iconX = 0;
|
||
pCD->pWsList[k].iconY = 0;
|
||
pCD->pWsList[k].iconFrameWin = (Window) 0;
|
||
pCD->pWsList[k].pIconBox = NULL;
|
||
}
|
||
}
|
||
|
||
|
||
/* update the client's list of workspace data */
|
||
pCD->pWsList[i].wsID = pWS->id;
|
||
pCD->numInhabited++;
|
||
|
||
if (!(pCD->clientFlags & WM_INITIALIZATION))
|
||
{
|
||
/*
|
||
* Make sure there's an icon
|
||
* (Don't do this during initialization, the pCD not
|
||
* ready for icon making yet).
|
||
*/
|
||
InsureIconForWorkspace (pWS, pCD);
|
||
}
|
||
|
||
/* update the workspace list of clients */
|
||
AddClientToWsList (pWS, pCD);
|
||
|
||
} /* END OF FUNCTION PutClientIntoWorkspace */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* TakeClientOutOfWorkspace (pWS, pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function updates the data for the client and the workspace
|
||
* to reflect the removal of the client from the workspace.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pWS = pointer to workspace data
|
||
* pCD = pointer to client data
|
||
*
|
||
* Outputs:
|
||
* --------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
TakeClientOutOfWorkspace(
|
||
WmWorkspaceData *pWS,
|
||
ClientData *pCD )
|
||
|
||
{
|
||
int ixA;
|
||
Boolean Copying = False;
|
||
WsClientData *pWsc;
|
||
|
||
if (pWS && pCD && ClientInWorkspace(pWS, pCD))
|
||
{
|
||
/*
|
||
* Clean up icon
|
||
*/
|
||
if (!pCD->transientLeader)
|
||
{
|
||
pWsc = GetWsClientData (pWS, pCD);
|
||
|
||
if ((pCD->pSD->useIconBox) &&
|
||
(pWsc->pIconBox) &&
|
||
(pCD->clientFunctions & MWM_FUNC_MINIMIZE))
|
||
{
|
||
DeleteIconFromBox (pWS->pIconBox, pCD);
|
||
}
|
||
else if (wmGD.iconAutoPlace)
|
||
{
|
||
/*
|
||
* Free up root icon spot
|
||
*/
|
||
|
||
if ((pWsc->iconPlace != NO_ICON_PLACE) &&
|
||
(pWS->IPData.placeList[pWsc->iconPlace].pCD == pCD))
|
||
{
|
||
pWS->IPData.placeList[pWsc->iconPlace].pCD = NULL;
|
||
pWsc->iconPlace = NO_ICON_PLACE;
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Remove the selected workspace and copy the remaining ones
|
||
* up. (Do piece-wise to avoid overlapping copy.)
|
||
*/
|
||
for (ixA = 0; ixA < pCD->numInhabited; ixA++)
|
||
{
|
||
if (Copying)
|
||
{
|
||
memcpy (&pCD->pWsList[ixA-1], &pCD->pWsList[ixA],
|
||
sizeof(WsClientData));
|
||
}
|
||
else if (pCD->pWsList[ixA].wsID == pWS->id)
|
||
{
|
||
/*
|
||
* This is the one we're removing, start copying here.
|
||
*/
|
||
Copying = True;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Decrement the number of workspaces inhabited.
|
||
*/
|
||
pCD->numInhabited--;
|
||
|
||
/* update the workspaces list of clients */
|
||
RemoveClientFromWsList (pWS, pCD);
|
||
}
|
||
#ifdef DEBUG
|
||
else
|
||
{
|
||
Warning("TakeClientOutOfWorkspace: null workspace passed in.");
|
||
}
|
||
#endif /* DEBUG */
|
||
|
||
|
||
} /* END OF FUNCTION TakeClientOutOfWorkspace */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* GetWorkspaceData (pSD, wsID)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function finds the data that is associated with a workspace ID.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pSD = pointer to screen data
|
||
* wsID = workspace ID
|
||
*
|
||
* Outputs:
|
||
* --------
|
||
* Function returns a pointer to the workspace data if successful,
|
||
* or NULL if unsuccessful.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
WmWorkspaceData *
|
||
GetWorkspaceData(
|
||
WmScreenData *pSD,
|
||
WorkspaceID wsID )
|
||
|
||
{
|
||
WmWorkspaceData *pWS = NULL;
|
||
int i;
|
||
|
||
for (i=0; i < pSD->numWorkspaces; i++)
|
||
{
|
||
if (pSD->pWS[i].id == wsID)
|
||
{
|
||
pWS = &pSD->pWS[i];
|
||
break;
|
||
}
|
||
}
|
||
|
||
#ifdef DEBUG
|
||
if (!pWS)
|
||
{
|
||
/* failed to find one */
|
||
Warning ("Failed to find workspace data");
|
||
}
|
||
#endif
|
||
|
||
return (pWS);
|
||
|
||
} /* END OF FUNCTION GetWorkspaceData */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* GenerateWorkspaceName (pSD, wsnum)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function generates and returns a workspace string name from
|
||
* a small number passed in.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pSD = pointer to screen data
|
||
* wsNum = number for workspace
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* returns pointer to statically allocated data. You must copy it
|
||
* to your local buffer.
|
||
*
|
||
* Comments:
|
||
* ---------
|
||
* Name is of the form ws<n> where <n> is a number.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
unsigned char *
|
||
GenerateWorkspaceName(
|
||
WmScreenData *pSD,
|
||
int wsnum )
|
||
|
||
{
|
||
static unsigned char nameReturned[13];
|
||
int i, j;
|
||
|
||
/*
|
||
* Nice n-squared algorithm...
|
||
* (This should be OK for small number of workspaces)
|
||
*/
|
||
for (i=0; i <= pSD->numWorkspaces; i++)
|
||
{
|
||
/* generate a name */
|
||
sprintf ((char *)nameReturned, "ws%d", i);
|
||
if (!DuplicateWorkspaceName (pSD, nameReturned, wsnum))
|
||
break;
|
||
}
|
||
|
||
return (nameReturned);
|
||
|
||
} /* END OF FUNCTION GenerateWorkspaceName */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* InWindowList (w, wl, num)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function determines if a window is in a list of windows
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* w = window of interest
|
||
* wl = list of windows
|
||
* num = number of windows in wl
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* The function returns "True" if "w" appears in "wl"
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
InWindowList(
|
||
Window w,
|
||
Window wl[],
|
||
int num )
|
||
|
||
{
|
||
int i;
|
||
Boolean rval = False;
|
||
|
||
for (i = 0; (i < num) && !rval; i++)
|
||
{
|
||
if (w == wl[i])
|
||
{
|
||
rval = True;
|
||
}
|
||
}
|
||
|
||
return (rval);
|
||
|
||
} /* END OF FUNCTION InWindowList */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* ClientInWorkspace (pWS, pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function determines if a client is in a workspace
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pWS = pointer to workspace data
|
||
* pCD = pointer to client data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* The function returns "True" if client pCD is in workspace pWS
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
ClientInWorkspace(
|
||
WmWorkspaceData *pWS,
|
||
ClientData *pCD )
|
||
|
||
{
|
||
int i;
|
||
Boolean rval = False;
|
||
|
||
for (i = 0; (i < pCD->numInhabited) && !rval; i++)
|
||
{
|
||
if (pWS->id == pCD->pWsList[i].wsID)
|
||
{
|
||
rval = True;
|
||
}
|
||
}
|
||
|
||
return (rval);
|
||
|
||
} /* END OF FUNCTION ClientInWorkspace */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* GetWsClientData (pWS, pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function returns a pointer to the client's specific data for
|
||
* this workspace
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pWS = pointer to workspace data
|
||
* pCD = pointer to client data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* The function returns a pointer to the client's data for this
|
||
* workspace. If the client isn't in the workspace, an error is
|
||
* printed and the first datum in the workspace list is returned.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
WsClientData *
|
||
GetWsClientData(
|
||
WmWorkspaceData *pWS,
|
||
ClientData *pCD )
|
||
|
||
{
|
||
int i;
|
||
WsClientData *pWsc = NULL;
|
||
|
||
for (i = 0; (i < pCD->numInhabited) && !pWsc; i++)
|
||
{
|
||
if (pWS->id == pCD->pWsList[i].wsID)
|
||
{
|
||
pWsc = &pCD->pWsList[i];
|
||
}
|
||
}
|
||
|
||
if (!pWsc)
|
||
{
|
||
pWsc = &pCD->pWsList[0];
|
||
}
|
||
|
||
return (pWsc);
|
||
|
||
} /* END OF FUNCTION GetWsClientData */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* SetClientWsIndex (pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function sets the index into the client's array of workspace
|
||
* specific data. This index points to the data to be used for the
|
||
* currently active workspace.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* The function returns an index as described above. If the client is
|
||
* not in the currently active workspace, then the index returned is 0.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
SetClientWsIndex(
|
||
ClientData *pCD )
|
||
|
||
{
|
||
int i;
|
||
WmWorkspaceData *pWS = pCD->pSD->pActiveWS;
|
||
|
||
for (i = 0; (i < pCD->numInhabited); i++)
|
||
{
|
||
if (pWS->id == pCD->pWsList[i].wsID)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (i >= pCD->numInhabited)
|
||
{
|
||
i = 0;
|
||
}
|
||
|
||
pCD->currentWsc = i;
|
||
|
||
} /* END OF FUNCTION SetClientWsIndex */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* ProcessWmWorkspaceHints (pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function processes a change to the _DT_WORKSPACE_HINTS property
|
||
* on a window that we manage.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* Returns False if we ran out of memory or no hints.
|
||
* Returns True on success.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
ProcessWorkspaceHints(
|
||
ClientData *pCD )
|
||
|
||
{
|
||
Atom *pIDs;
|
||
int i, j;
|
||
unsigned int numIDs;
|
||
WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
|
||
Boolean rval = False;
|
||
Boolean InBoth;
|
||
Boolean bAll;
|
||
int numOld;
|
||
WorkspaceID *pDiff = NULL;
|
||
int numDiff;
|
||
|
||
numOld = pCD->numInhabited;
|
||
ReserveIdListSpace (numOld);
|
||
for (i = 0; i < numOld; i++)
|
||
{
|
||
pResIDs[i] = pCD->pWsList[i].wsID;
|
||
}
|
||
|
||
if ((pCD->client) &&
|
||
(GetWorkspaceHints (DISPLAY, pCD->client,
|
||
&pIDs, &numIDs, &bAll) == Success) &&
|
||
(bAll || (numIDs && (pDiff = (WorkspaceID *)
|
||
XtMalloc (sizeof(WorkspaceID) * MAX(numIDs, numOld))))))
|
||
{
|
||
/*
|
||
* Process request to put window in all workspaces
|
||
*/
|
||
pCD->putInAll = bAll;
|
||
CheckForPutInAllRequest (pCD, pIDs, numIDs);
|
||
|
||
if (!pCD->putInAll)
|
||
{
|
||
/*
|
||
* Compute the ids to be removed.
|
||
*/
|
||
numDiff = 0;
|
||
|
||
for (i=0; i < numOld; i++)
|
||
{
|
||
InBoth = False;
|
||
for (j=0; j < numIDs; j++)
|
||
{
|
||
if (pIDs[j] == pResIDs[i])
|
||
{
|
||
InBoth = True;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!InBoth)
|
||
{
|
||
pDiff[numDiff++] = pResIDs[i];
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Remove the client from the set of workspaces
|
||
*/
|
||
if (numDiff)
|
||
{
|
||
RemoveClientFromWorkspaces (pCD, pDiff, numDiff);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Process request to put window in all workspaces
|
||
*/
|
||
|
||
if (pCD->putInAll)
|
||
{
|
||
for (i=0; i<pCD->pSD->numWorkspaces; i++)
|
||
{
|
||
if (!ClientInWorkspace(&pCD->pSD->pWS[i], pCD))
|
||
{
|
||
AddClientToWorkspaces (pCD, &pCD->pSD->pWS[i].id, 1);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* Compute the ids to be added.
|
||
*/
|
||
|
||
numDiff = 0;
|
||
for (i=0; i < numIDs; i++)
|
||
{
|
||
InBoth = False;
|
||
for (j=0; j < numOld; j++)
|
||
{
|
||
if (pResIDs[j] == pIDs[i])
|
||
{
|
||
InBoth = True;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!InBoth)
|
||
{
|
||
pDiff[numDiff++] = pIDs[i];
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Add the client to the set of workspaces
|
||
*/
|
||
if (numDiff)
|
||
{
|
||
AddClientToWorkspaces (pCD, pDiff, numDiff);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* If the client is not in any workspaces, then
|
||
* put it in the current one
|
||
*
|
||
* !!! Is this right? !!!
|
||
*/
|
||
if (pCD->numInhabited == 0)
|
||
{
|
||
AddClientToWorkspaces (pCD, &pSD->pActiveWS->id, 1);
|
||
}
|
||
|
||
/*
|
||
* Free up the old list of hints
|
||
*/
|
||
if (pCD->pWorkspaceHints)
|
||
{
|
||
XFree ((char *)pCD->pWorkspaceHints);
|
||
}
|
||
if (pDiff)
|
||
{
|
||
XtFree ((char *)pDiff);
|
||
}
|
||
|
||
/*
|
||
* Save the new hints
|
||
*/
|
||
pCD->pWorkspaceHints = pIDs;
|
||
pCD->numWorkspaceHints = numIDs;
|
||
|
||
/*
|
||
* Update the presence property
|
||
*/
|
||
UpdateWorkspacePresenceProperty (pCD);
|
||
|
||
rval = True;
|
||
}
|
||
return (rval);
|
||
|
||
} /* END OF FUNCTION ProcessWorkspaceHints */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* InsureUniqueWorkspaceHints (pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function processes the workspace hints and removes duplicates.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* May modify *pWorkspaceHints and numWorkspaceHints
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
static void
|
||
InsureUniqueWorkspaceHints(
|
||
ClientData *pCD )
|
||
|
||
{
|
||
int next, trail, i;
|
||
WorkspaceID *pID;
|
||
Boolean duplicate;
|
||
|
||
|
||
if (pCD->numWorkspaceHints < 2) return;
|
||
|
||
pID = pCD->pWorkspaceHints;
|
||
|
||
trail = 0;
|
||
next = 1;
|
||
|
||
while (next < pCD->numWorkspaceHints)
|
||
{
|
||
duplicate = False;
|
||
for (i = 0; i < next; i++)
|
||
{
|
||
if (pID [next] == pID [i])
|
||
{
|
||
/* duplicate found! */
|
||
duplicate = True;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (duplicate)
|
||
{
|
||
/* skip duplicates */
|
||
next++;
|
||
}
|
||
else
|
||
{
|
||
/* not a duplicate */
|
||
trail++;
|
||
if (next > trail)
|
||
{
|
||
/*
|
||
* We need to copy up over an old duplicate
|
||
*/
|
||
pID [trail] = pID [next];
|
||
}
|
||
}
|
||
next++;
|
||
}
|
||
|
||
pCD->numWorkspaceHints = trail+1;
|
||
|
||
} /* END OF FUNCTION InsureUniqueWorkspaceHints */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* ProcessWorkspaceHintList (pCD, pIDs, numIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function processes a list of workspace hints for a client.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
* pIDs = pointer to a list of workspace IDs
|
||
* numIDs = number of IDs in the list
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
ProcessWorkspaceHintList(
|
||
ClientData *pCD,
|
||
WorkspaceID *pIDs,
|
||
unsigned int numIDs )
|
||
|
||
{
|
||
int i;
|
||
WmWorkspaceData *pWS;
|
||
|
||
|
||
if (numIDs > 0)
|
||
{
|
||
/*
|
||
* Keep these hints; make sure there are no duplicate
|
||
* workspace requests.
|
||
*/
|
||
pCD->pWorkspaceHints = pIDs;
|
||
pCD->numWorkspaceHints = numIDs;
|
||
InsureUniqueWorkspaceHints (pCD);
|
||
numIDs = pCD->numWorkspaceHints;
|
||
|
||
if (pCD->pWorkspaceHints)
|
||
{
|
||
/*
|
||
* Process request to put window in all workspaces
|
||
*/
|
||
CheckForPutInAllRequest (pCD, pIDs, numIDs);
|
||
|
||
if (pCD->putInAll)
|
||
{
|
||
for (i=0; i<pCD->pSD->numWorkspaces; i++)
|
||
{
|
||
PutClientIntoWorkspace (&pCD->pSD->pWS[i], pCD);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (i=0; i<numIDs; i++)
|
||
{
|
||
/*
|
||
* Put the client into requested workspaces that
|
||
* exist.
|
||
*/
|
||
if ((pWS = GetWorkspaceData (pCD->pSD,
|
||
pCD->pWorkspaceHints[i])))
|
||
{
|
||
PutClientIntoWorkspace (pWS, pCD);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
} /* END OF FUNCTION ProcessWorkspaceHintList */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* RemoveSingleClientFromWorkspaces (pCD, pIDs, numIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function removes a single client from a list of workspaces
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
* pIDs = pointer to a list of workspace IDs
|
||
* numIDs = number of workspace IDs
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
RemoveSingleClientFromWorkspaces(
|
||
ClientData *pCD,
|
||
WorkspaceID *pIDs,
|
||
unsigned int numIDs )
|
||
|
||
{
|
||
int i;
|
||
WmWorkspaceData *pWS;
|
||
|
||
for (i=0; i < numIDs; i++)
|
||
{
|
||
/*
|
||
* Remove the client from the specified workspaces
|
||
*/
|
||
if ((pWS = GetWorkspaceData (pCD->pSD, pIDs[i])) &&
|
||
(ClientInWorkspace (pWS, pCD)))
|
||
{
|
||
/*
|
||
* If this workspace is active, then make the
|
||
* window unseen. We only need to call
|
||
* SetClientState on the main window, the
|
||
* transients will get taken care of in there.
|
||
*/
|
||
if ((pWS == pCD->pSD->pActiveWS) &&
|
||
(pCD->transientLeader == NULL) &&
|
||
!(pCD->clientState & UNSEEN_STATE))
|
||
{
|
||
SetClientState (pCD,
|
||
(pCD->clientState | UNSEEN_STATE), CurrentTime);
|
||
}
|
||
TakeClientOutOfWorkspace (pWS, pCD);
|
||
|
||
/*
|
||
* Update the presence property
|
||
*/
|
||
UpdateWorkspacePresenceProperty (pCD);
|
||
}
|
||
}
|
||
|
||
} /* END OF FUNCTION RemoveSingleClientFromWorkspaces */
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* RemoveSubtreeFromWorkspaces (pCD, pIDs, numIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function removes a transient subtree from a list of workspaces
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
* pIDs = pointer to a list of workspace IDs
|
||
* numIDs = number of workspace IDs
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
RemoveSubtreeFromWorkspaces(
|
||
ClientData *pCD,
|
||
WorkspaceID *pIDs,
|
||
unsigned int numIDs )
|
||
|
||
{
|
||
ClientData *pNext;
|
||
|
||
pNext = pCD->transientChildren;
|
||
while (pNext)
|
||
{
|
||
/* process all children first */
|
||
if (pNext->transientChildren)
|
||
{
|
||
RemoveSubtreeFromWorkspaces (pNext, pIDs, numIDs);
|
||
}
|
||
else
|
||
{
|
||
RemoveSingleClientFromWorkspaces (pNext, pIDs, numIDs);
|
||
}
|
||
pNext = pNext->transientSiblings;
|
||
}
|
||
|
||
/* process the primary window */
|
||
RemoveSingleClientFromWorkspaces (pCD, pIDs, numIDs);
|
||
|
||
|
||
} /* END OF FUNCTION RemoveSubtreeFromWorkspaces */
|
||
|
||
|
||
|
||
/******************************<->*************************************
|
||
*
|
||
* pIDs = GetListOfOccupiedWorkspaces (pCD, numIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function creates a list of occupied workspaces of a particular
|
||
* client, EXCLUDING the current workspace.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* pIDs = pointer to a list of workspace IDs
|
||
* numIDs = number of workspace IDs
|
||
*
|
||
* Comment
|
||
* -------
|
||
* memory for pIDs is allocated with XtMalloc and should be
|
||
* freed with XtFree.
|
||
*
|
||
*
|
||
******************************<->***********************************/
|
||
WorkspaceID *
|
||
GetListOfOccupiedWorkspaces(
|
||
ClientData *pCD,
|
||
int *numIDs )
|
||
{
|
||
int i;
|
||
|
||
WorkspaceID *pLocalIDs = NULL;
|
||
|
||
WorkspaceID activeWsID = pCD->pSD->pActiveWS->id;
|
||
|
||
*numIDs = 0;
|
||
|
||
if ((pLocalIDs = (WorkspaceID *) XtMalloc (pCD->numInhabited *
|
||
sizeof(WorkspaceID))) == NULL)
|
||
{
|
||
Warning (((char *)GETMESSAGE(76, 7, "Insufficient memory")));
|
||
return (NULL);
|
||
}
|
||
|
||
for (i = 0; i < pCD->numInhabited; i++)
|
||
{
|
||
if (activeWsID != pCD->pWsList[i].wsID)
|
||
{
|
||
pLocalIDs[(*numIDs)++] = pCD->pWsList[i].wsID;
|
||
}
|
||
}
|
||
|
||
return(pLocalIDs);
|
||
|
||
} /* END OF FUNCTION GetListOfOccupiedWorkspaces */
|
||
|
||
|
||
/******************************<->*************************************
|
||
*
|
||
* HonorAbsentMapBehavior(pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function adds a client to the current workspace and
|
||
* if (pCD->absentMapBehavior == AMAP_BEHAVIOR_MOVE)
|
||
* removes the client from the other workspaces
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
******************************<->***********************************/
|
||
|
||
void
|
||
HonorAbsentMapBehavior(
|
||
ClientData *pCD)
|
||
{
|
||
int inWorkspace = 0;
|
||
|
||
if (pCD->absentMapBehavior == AMAP_BEHAVIOR_MOVE)
|
||
{
|
||
int wsCnt;
|
||
|
||
/*
|
||
* Remove from other workspaces
|
||
*/
|
||
for (wsCnt = 0; wsCnt < pCD->numInhabited; wsCnt = inWorkspace)
|
||
{
|
||
if (pCD->pWsList[wsCnt].wsID != pCD->pSD->pActiveWS->id)
|
||
{
|
||
RemoveClientFromWorkspaces (pCD,
|
||
&pCD->pWsList[wsCnt].wsID, 1);
|
||
}
|
||
else inWorkspace++;
|
||
}
|
||
}
|
||
|
||
if (inWorkspace == 0)
|
||
AddClientToWorkspaces (pCD, &ACTIVE_WS->id, 1);
|
||
|
||
} /* END OF FUNCTION HonorAbsentMapBehavior */
|
||
|
||
|
||
|
||
/******************************<->*************************************
|
||
*
|
||
* RemoveClientFromWorkspaces (pCD, pIDs, numIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function removes a client from a list of workspaces
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
* pIDs = pointer to a list of workspace IDs
|
||
* numIDs = number of workspace IDs
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
******************************<->***********************************/
|
||
|
||
void
|
||
RemoveClientFromWorkspaces(
|
||
ClientData *pCD,
|
||
WorkspaceID *pIDs,
|
||
unsigned int numIDs )
|
||
|
||
{
|
||
ClientData *pcdLeader;
|
||
|
||
pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
|
||
|
||
RemoveSubtreeFromWorkspaces (pcdLeader, pIDs, numIDs);
|
||
|
||
|
||
} /* END OF FUNCTION RemoveClientFromWorkspaces */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* AddSingleClientToWorkspaces (pCD, pIDs, numIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function adds a single client to a list of workspaces
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
* pIDs = pointer to a list of workspace IDs
|
||
* numIDs = number of workspace IDs
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
AddSingleClientToWorkspaces(
|
||
ClientData *pCD,
|
||
WorkspaceID *pIDs,
|
||
unsigned int numIDs )
|
||
|
||
{
|
||
int i;
|
||
WmWorkspaceData *pWS;
|
||
|
||
for (i=0; i < numIDs; i++)
|
||
{
|
||
/*
|
||
* Add the client to the specified workspaces if
|
||
* it is not already there.
|
||
*/
|
||
if ((pWS = GetWorkspaceData (pCD->pSD, pIDs[i])) &&
|
||
(!ClientInWorkspace (pWS, pCD)))
|
||
{
|
||
PutClientIntoWorkspace (pWS, pCD);
|
||
|
||
if ((pWS == PSD_FOR_CLIENT(pCD)->pActiveWS) &&
|
||
(pCD->transientLeader == NULL) &&
|
||
(pCD->clientState & UNSEEN_STATE))
|
||
{
|
||
SetClientState (pCD,
|
||
(pCD->clientState & ~UNSEEN_STATE), CurrentTime);
|
||
}
|
||
|
||
/*
|
||
* Update the presence property (only on transient leader)
|
||
*/
|
||
UpdateWorkspacePresenceProperty (pCD);
|
||
|
||
}
|
||
}
|
||
} /* END OF FUNCTION AddSingleClientToWorkspace */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* AddSubtreeToWorkspaces (pCD, pIDs, numIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function adds a client subtree to a list of workspaces
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data (head of subtree)
|
||
* pIDs = pointer to a list of workspace IDs
|
||
* numIDs = number of workspace IDs
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
AddSubtreeToWorkspaces(
|
||
ClientData *pCD,
|
||
WorkspaceID *pIDs,
|
||
unsigned int numIDs )
|
||
|
||
{
|
||
ClientData *pNext;
|
||
|
||
pNext = pCD->transientChildren;
|
||
while (pNext)
|
||
{
|
||
/* process all children first */
|
||
if (pNext->transientChildren)
|
||
{
|
||
AddSubtreeToWorkspaces (pNext, pIDs, numIDs);
|
||
}
|
||
else
|
||
{
|
||
AddSingleClientToWorkspaces (pNext, pIDs, numIDs);
|
||
}
|
||
pNext = pNext->transientSiblings;
|
||
}
|
||
|
||
/* process the primary window */
|
||
AddSingleClientToWorkspaces (pCD, pIDs, numIDs);
|
||
|
||
|
||
} /* END OF FUNCTION AddSubtreeToWorkspaces */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* AddClientToWorkspaces (pCD, pIDs, numIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function adds a transient tree to a list of workspaces
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
* pIDs = pointer to a list of workspace IDs
|
||
* numIDs = number of workspace IDs
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
AddClientToWorkspaces(
|
||
ClientData *pCD,
|
||
WorkspaceID *pIDs,
|
||
unsigned int numIDs )
|
||
|
||
{
|
||
ClientData *pcdLeader;
|
||
|
||
pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
|
||
|
||
AddSubtreeToWorkspaces (pcdLeader, pIDs, numIDs);
|
||
|
||
} /* END OF FUNCTION AddClientToWorkspaces */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* AddClientToWsList (pWS, pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function adds a client to a list of clients in a workspace
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
* pWS = pointer to workspace data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* none
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
AddClientToWsList(
|
||
WmWorkspaceData *pWS,
|
||
ClientData *pCD )
|
||
|
||
{
|
||
if (pWS->numClients >= pWS->sizeClientList)
|
||
{
|
||
if (pWS->sizeClientList == 0)
|
||
{
|
||
pWS->ppClients = (ClientData **)
|
||
XtMalloc (WINDOW_ALLOC_AMOUNT * sizeof(ClientData *));
|
||
}
|
||
else
|
||
{
|
||
pWS->ppClients = (ClientData **)
|
||
XtRealloc ((char *)pWS->ppClients,
|
||
(pWS->sizeClientList + WINDOW_ALLOC_AMOUNT) *
|
||
sizeof(ClientData *));
|
||
}
|
||
|
||
if (!pWS->ppClients)
|
||
{
|
||
Warning (((char *)GETMESSAGE(76, 9, "Insufficient memory to add window to workspace")));
|
||
ExitWM(WM_ERROR_EXIT_VALUE);
|
||
}
|
||
|
||
pWS->sizeClientList += WINDOW_ALLOC_AMOUNT;
|
||
}
|
||
|
||
if (pWS->numClients < pWS->sizeClientList)
|
||
{
|
||
pWS->ppClients[pWS->numClients] = pCD;
|
||
pWS->numClients++;
|
||
}
|
||
} /* END OF FUNCTION AddClientToWsList */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* RemoveClientFromWsList (pWS, pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function removes a client from a list of clients in a workspace
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
* pWS = pointer to workspace data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* none
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
RemoveClientFromWsList(
|
||
WmWorkspaceData *pWS,
|
||
ClientData *pCD )
|
||
|
||
{
|
||
int src, dest;
|
||
|
||
for (dest = 0; dest < pWS->numClients; dest++)
|
||
{
|
||
if (pWS->ppClients[dest] == pCD)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
for (src = dest+1; src < pWS->numClients; src++, dest++)
|
||
{
|
||
pWS->ppClients[dest] = pWS->ppClients[src];
|
||
}
|
||
|
||
pWS->numClients--;
|
||
|
||
} /* END OF FUNCTION RemoveClientFromWsList */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* Boolean
|
||
* F_CreateWorkspace (args, pCD, event)
|
||
*
|
||
* Description:
|
||
* -----------
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* args = ...
|
||
* pCD = ...
|
||
* event = ...
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* Return = ...
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
F_CreateWorkspace(
|
||
String args,
|
||
ClientData *pCD,
|
||
XEvent *event )
|
||
|
||
{
|
||
WmScreenData *pSD = ACTIVE_PSD;
|
||
|
||
if (pSD->numWorkspaces >= MAX_WORKSPACE_COUNT)
|
||
{
|
||
char buffer[MAXWMPATH];
|
||
/*
|
||
* At the maximum number of allowed workspaces.
|
||
*/
|
||
sprintf (buffer,
|
||
((char *)GETMESSAGE(76, 14, "Maximum number of workspaces is %d. New workspace was not created.")), MAX_WORKSPACE_COUNT);
|
||
Warning (buffer);
|
||
}
|
||
else
|
||
{
|
||
CreateWorkspace (ACTIVE_PSD, (unsigned char *)args);
|
||
}
|
||
|
||
return (TRUE);
|
||
|
||
} /* END OF FUNCTION F_CreateWorkspace */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* Boolean
|
||
* F_DeleteWorkspace (args, pCD, event)
|
||
*
|
||
* Description:
|
||
* -----------
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* args = ...
|
||
* pCD = ...
|
||
* event = ...
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* Return = ...
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
F_DeleteWorkspace(
|
||
String args,
|
||
ClientData *pCD,
|
||
XEvent *event )
|
||
|
||
{
|
||
WmScreenData *pSD = ACTIVE_PSD;
|
||
WmWorkspaceData *pWS = NULL;
|
||
int i;
|
||
|
||
if (args == NULL)
|
||
{
|
||
pWS= ACTIVE_WS;
|
||
}
|
||
else
|
||
{
|
||
for (i=0; i<pSD->numWorkspaces; i++)
|
||
{
|
||
if (!strcmp(pSD->pWS[i].name, args))
|
||
{
|
||
pWS = &(pSD->pWS[i]);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (pWS)
|
||
DeleteWorkspace (pWS);
|
||
|
||
return (TRUE);
|
||
|
||
} /* END OF FUNCTION F_DeleteWorkspace */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* Boolean
|
||
* F_GotoWorkspace (args, pCD, event)
|
||
*
|
||
* Description:
|
||
* -----------
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* args = ...
|
||
* pCD = ...
|
||
* event = ...
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* Return = ...
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
F_GotoWorkspace(
|
||
String args,
|
||
ClientData *pCD,
|
||
XEvent *event )
|
||
|
||
{
|
||
WorkspaceID wsID;
|
||
WmWorkspaceData *pWS;
|
||
|
||
wsID = XInternAtom (DISPLAY, args, False);
|
||
pWS = GetWorkspaceData (ACTIVE_PSD, wsID);
|
||
|
||
if (pWS)
|
||
{
|
||
ChangeToWorkspace (pWS);
|
||
}
|
||
return (TRUE);
|
||
|
||
} /* END OF FUNCTION F_GotoWorkspace */
|
||
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* Boolean
|
||
* F_AddToAllWorkspaces (args, pCD, event)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Puts a client into all workspaces
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* args = ...
|
||
* pCD = pointer to client data
|
||
* event = ...
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* Return = True
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
* The list of Ids returned has been privately allocated. Copy
|
||
* if you want to save or do anything with it.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
F_AddToAllWorkspaces(
|
||
String args,
|
||
ClientData *pCD,
|
||
XEvent *event )
|
||
|
||
{
|
||
WmScreenData *pSD;
|
||
int i;
|
||
|
||
if (pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS))
|
||
{
|
||
pSD = pCD->pSD;
|
||
|
||
ReserveIdListSpace (pSD->numWorkspaces);
|
||
|
||
for (i = 0; i < pSD->numWorkspaces; i++)
|
||
{
|
||
pResIDs[i] = pSD->pWS[i].id;
|
||
}
|
||
|
||
AddClientToWorkspaces (pCD, pResIDs, pSD->numWorkspaces);
|
||
|
||
pCD->putInAll = True;
|
||
}
|
||
|
||
return (True);
|
||
|
||
} /* END OF FUNCTION F_AddToAllWorkspaces */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* Boolean
|
||
* F_Remove (args, pCD, event)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Removes a client from the current workspace
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* args = ...
|
||
* pCD = pointer to client data
|
||
* event = ...
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* Return = True
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
F_Remove(
|
||
String args,
|
||
ClientData *pCD,
|
||
XEvent *event )
|
||
|
||
{
|
||
Boolean rval = False;
|
||
|
||
/*
|
||
* Only remove if in more than one workspace.
|
||
*/
|
||
if ((pCD && (pCD->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS)) &&
|
||
(pCD->numInhabited > 1))
|
||
{
|
||
if (ClientInWorkspace (ACTIVE_WS, pCD))
|
||
{
|
||
RemoveClientFromWorkspaces (pCD, &ACTIVE_WS->id, 1);
|
||
pCD->putInAll = False;
|
||
}
|
||
}
|
||
|
||
return (rval);
|
||
|
||
} /* END OF FUNCTION F_Remove */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* GetCurrentWorkspaceIndex (pSD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Returns an index into the screens array of workspace structures
|
||
* for the current workspace.
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*************************************<->***********************************/
|
||
int
|
||
GetCurrentWorkspaceIndex(
|
||
WmScreenData *pSD )
|
||
{
|
||
|
||
int i;
|
||
|
||
for (i = 0 ; i < pSD->numWorkspaces; i++)
|
||
{
|
||
if (pSD->pWS[i].id == pSD->pActiveWS->id)
|
||
break;
|
||
}
|
||
|
||
if (i >= pSD->numWorkspaces)
|
||
{
|
||
/* failed to find workspace!!! How did that happen??? */
|
||
i = 0;
|
||
#ifdef DEBUG
|
||
Warning ("Failed to find workspace index");
|
||
#endif /* DEBUG */
|
||
}
|
||
|
||
return(i);
|
||
} /* END OF FUNCTION GetCurrentWorkspaceIndex */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* void
|
||
* InsureIconForWorkspace (pWS, pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Makes sure an icon exists for the workspace
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
InsureIconForWorkspace(
|
||
WmWorkspaceData *pWS,
|
||
ClientData *pCD )
|
||
|
||
{
|
||
WsClientData *pWsc;
|
||
|
||
if (pCD->clientFunctions & MWM_FUNC_MINIMIZE)
|
||
{
|
||
pWsc = GetWsClientData (pWS, pCD);
|
||
|
||
if ((pCD->pSD->useIconBox) &&
|
||
(!(pCD->clientFlags & (CLIENT_WM_CLIENTS | FRONT_PANEL_BOX))))
|
||
{
|
||
/*
|
||
* Create a new widget for the icon box
|
||
*/
|
||
if (MakeIcon (pWS, pCD))
|
||
{
|
||
XSaveContext (DISPLAY, pWsc->iconFrameWin,
|
||
wmGD.windowContextType, (caddr_t)pCD);
|
||
|
||
if (pCD->iconWindow && pWsc->iconFrameWin)
|
||
{
|
||
XGrabButton (DISPLAY, AnyButton, AnyModifier,
|
||
pWsc->iconFrameWin, True,
|
||
ButtonPressMask|ButtonReleaseMask|
|
||
ButtonMotionMask,
|
||
GrabModeAsync, GrabModeAsync, None,
|
||
wmGD.workspaceCursor);
|
||
}
|
||
|
||
ShowClientIconState (pCD, (pCD->clientState & ~UNSEEN_STATE));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* Reuse existing icon in new workspaces. Suggest
|
||
* icon position in current WS as position of icon
|
||
* in new WS.
|
||
*/
|
||
pWsc->iconFrameWin = pCD->pWsList[0].iconFrameWin;
|
||
pWsc->iconX = ICON_X(pCD);
|
||
pWsc->iconY = ICON_Y(pCD);
|
||
|
||
if ((pCD->clientState & ~UNSEEN_STATE) != MINIMIZED_STATE)
|
||
{
|
||
pWsc->iconPlace = NO_ICON_PLACE;
|
||
}
|
||
else if (!wmGD.iconAutoPlace)
|
||
{
|
||
if (wmGD.positionIsFrame)
|
||
{
|
||
pWsc->iconX -= pCD->clientOffset.x;
|
||
pWsc->iconY -= pCD->clientOffset.y;
|
||
}
|
||
PlaceIconOnScreen (pCD, &pWsc->iconX, &pWsc->iconY);
|
||
}
|
||
else /* icon auto placement */
|
||
{
|
||
pWsc->iconPlace =
|
||
CvtIconPositionToPlace (&pWS->IPData,
|
||
pWsc->iconX, pWsc->iconY);
|
||
if (pWS->IPData.placeList[pWsc->iconPlace].pCD)
|
||
{
|
||
/* The spot is already occupied! Find a
|
||
spot nearby. */
|
||
pWsc->iconPlace =
|
||
FindIconPlace (pCD, &pWS->IPData, pWsc->iconX,
|
||
pWsc->iconY);
|
||
|
||
if (pWsc->iconPlace == NO_ICON_PLACE)
|
||
{
|
||
/* Can't find a spot close by. Use the
|
||
next available slot */
|
||
pWsc->iconPlace = GetNextIconPlace (&pWS->IPData);
|
||
if (pWsc->iconPlace == NO_ICON_PLACE)
|
||
{
|
||
pWsc->iconPlace =
|
||
CvtIconPositionToPlace (&pWS->IPData,
|
||
pCD->clientX,
|
||
pCD->clientY);
|
||
}
|
||
}
|
||
}
|
||
CvtIconPlaceToPosition (&pWS->IPData, pWsc->iconPlace,
|
||
&pWsc->iconX, &pWsc->iconY);
|
||
|
||
|
||
if (!(pWS->IPData.placeList[pWsc->iconPlace].pCD))
|
||
{
|
||
pWS->IPData.placeList[pWsc->iconPlace].pCD = pCD;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} /* END OF FUNCTION InsureIconForWorkspace */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* Boolean
|
||
* GetLeaderPresence (pCD, pIDs, pnumIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Gets the workspace presence of the transient tree leader for a
|
||
* client.
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
* ppIDs = pointer to pointer to list of workspace ids
|
||
* pnumIDs = pointer to number of workspace ids
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* *ppIDS = list of workspace IDs
|
||
* *pnumIDs = number of workspace IDs in list
|
||
*
|
||
* Return = true on success
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
* ID list is dynamically allocated, please XtFree() it when you're
|
||
* done.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
GetLeaderPresence(
|
||
ClientData *pCD,
|
||
WorkspaceID **ppIDs,
|
||
unsigned int *pnumIDs )
|
||
|
||
{
|
||
ClientData *pcdLeader;
|
||
int i;
|
||
Boolean rval = False;
|
||
WorkspaceID *pLocalIDs;
|
||
|
||
if ((pLocalIDs = (WorkspaceID *) XtMalloc (pCD->pSD->numWorkspaces *
|
||
sizeof(WorkspaceID))) == NULL)
|
||
{
|
||
Warning (((char *)GETMESSAGE(76, 10, "Insufficient Memory (GetLeaderPresence)")));
|
||
ExitWM (WM_ERROR_EXIT_VALUE);
|
||
}
|
||
|
||
/*
|
||
* Make up list of workspaces for primary window
|
||
*/
|
||
if (pCD->transientLeader)
|
||
{
|
||
pcdLeader = FindTransientTreeLeader (pCD);
|
||
|
||
for (i = 0; i < pcdLeader->numInhabited; i++)
|
||
{
|
||
pLocalIDs[i] = pcdLeader->pWsList[i].wsID;
|
||
}
|
||
|
||
*ppIDs = pLocalIDs;
|
||
*pnumIDs = pcdLeader->numInhabited;
|
||
rval = True;
|
||
}
|
||
|
||
return (rval);
|
||
|
||
} /* END OF FUNCTION GetLeaderPresence */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* Boolean
|
||
* GetMyOwnPresence (pCD, pIDs, pnumIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Returns the current workspace presence for the client
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
* ppIDs = pointer to pointer to list of workspace ids
|
||
* pnumIDs = pointer to number of workspace ids
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* *ppIDS = list of workspace IDs
|
||
* *pnumIDs = number of workspace IDs in list
|
||
*
|
||
* Return = true on success
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
* ID list is dynamically allocated (by DtWsmGetWorkspacesOccupied).
|
||
* Please XtFree() it when you're done.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
GetMyOwnPresence(
|
||
ClientData *pCD,
|
||
WorkspaceID **ppIDs,
|
||
unsigned int *pnumIDs )
|
||
|
||
{
|
||
Boolean rval = False;
|
||
unsigned long nIDs = (unsigned long)*pnumIDs;
|
||
|
||
/*
|
||
* Get the workspace presence property
|
||
*/
|
||
if (
|
||
HasProperty (pCD, wmGD.xa_DT_WORKSPACE_PRESENCE)
|
||
&& (DtWsmGetWorkspacesOccupied (DISPLAY, pCD->client, ppIDs,
|
||
&nIDs) == Success))
|
||
{
|
||
if (nIDs)
|
||
{
|
||
rval = True;
|
||
}
|
||
}
|
||
*pnumIDs = (unsigned int)nIDs;
|
||
|
||
return (rval);
|
||
|
||
} /* END OF FUNCTION GetMyOwnPresence */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* void
|
||
* ReserveIdListSpace (numIDs)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Insures that there is enough room in our privately allocated
|
||
* list of workspace IDs
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* numIDs = number of workspace ids
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
ReserveIdListSpace(
|
||
int numIDs )
|
||
|
||
{
|
||
if (numResIDs == 0)
|
||
{
|
||
pResIDs = (WorkspaceID *)
|
||
XtMalloc (numIDs * sizeof (WorkspaceID));
|
||
if (pResIDs)
|
||
{
|
||
numResIDs = numIDs;
|
||
}
|
||
}
|
||
else if (numResIDs < numIDs)
|
||
{
|
||
pResIDs = (WorkspaceID *) XtRealloc ((char *)pResIDs,
|
||
numIDs * sizeof (WorkspaceID));
|
||
|
||
numResIDs = (pResIDs)? numIDs : 0;
|
||
}
|
||
|
||
if (pResIDs == NULL)
|
||
{
|
||
Warning (((char *)GETMESSAGE(76, 11, "Insufficient memory")));
|
||
ExitWM (WM_ERROR_EXIT_VALUE);
|
||
}
|
||
|
||
} /* END OF FUNCTION ReserveIdListSpace */
|
||
|
||
|
||
|
||
|
||
/******************************<->*************************************
|
||
*
|
||
* SaveResources (pSD)
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Saves dtwm resources to restore session
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pSD = pointer to screen data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* None
|
||
*
|
||
* Comments:
|
||
* ---------
|
||
*
|
||
*************************************<->***********************************/
|
||
void
|
||
SaveResources( WmScreenData *pSD)
|
||
{
|
||
int wsCnt;
|
||
WmPanelistObject pPanelist;
|
||
|
||
if(pSD)
|
||
{
|
||
if (pSD->pActiveWS)
|
||
{
|
||
SaveWorkspaceResources(pSD->pActiveWS,
|
||
(WM_RES_INITIAL_WORKSPACE |
|
||
WM_RES_WORKSPACE_COUNT));
|
||
}
|
||
|
||
pPanelist = (WmPanelistObject) pSD->wPanelist;
|
||
if (pPanelist && O_Shell(pPanelist))
|
||
{
|
||
/* This is the front panel for the screen */
|
||
SaveWorkspaceResources(pSD->pActiveWS,
|
||
WM_RES_FP_POSITION);
|
||
|
||
|
||
/* Call the fronto panel function to save its resources */
|
||
|
||
WmFrontPanelSessionSaveData();
|
||
}
|
||
|
||
|
||
|
||
for (wsCnt = 0; wsCnt < pSD->numWorkspaces; wsCnt++)
|
||
{
|
||
if(pSD->useIconBox)
|
||
{
|
||
SaveWorkspaceResources(&pSD->pWS[wsCnt],
|
||
WM_RES_ICONBOX_GEOMETRY);
|
||
}
|
||
} /* for wsCnt */
|
||
|
||
SaveHelpResources(pSD);
|
||
|
||
} /* if pSD */
|
||
|
||
} /* END OF FUNCTION SaveResources */
|
||
|
||
|
||
/******************************<->*************************************
|
||
*
|
||
* SaveWorkspaceResource (pWS, flags)
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Modifies the RESOURCE_MANAGER property to add update versions
|
||
* of the requested resources.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pWS = pointer to workspace data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* None
|
||
*
|
||
* Comments:
|
||
* ---------
|
||
*
|
||
*************************************<->***********************************/
|
||
void
|
||
SaveWorkspaceResources(
|
||
WmWorkspaceData *pWS,
|
||
unsigned long flags)
|
||
{
|
||
char *buffer = NULL;
|
||
int bufferLength = 0;
|
||
char *res_class;
|
||
char *data;
|
||
int cum_len;
|
||
|
||
char screenName[1024];
|
||
char tmpScreenName[10];
|
||
|
||
Position clientX;
|
||
Position clientY;
|
||
Dimension clientWidth;
|
||
Dimension clientHeight;
|
||
int xoff, yoff;
|
||
WmPanelistObject pPanelist = (WmPanelistObject) pWS->pSD->wPanelist;
|
||
ClientData *pCD_Panel ;
|
||
char tmpBuffer[MAXWMPATH+1];
|
||
int iLen;
|
||
|
||
/* allocate initial data space */
|
||
if ((data = (char *) XtMalloc (MAXWMPATH+1)) == NULL)
|
||
{
|
||
Warning (((char *)
|
||
GETMESSAGE(76,12,"Insufficient memory to save resources")));
|
||
Do_Quit_Mwm (False);
|
||
}
|
||
cum_len = 1;
|
||
*data = '\0';
|
||
|
||
if (bufferLength == 0)
|
||
{
|
||
buffer = (char *) XtMalloc (MAXWMPATH+1);
|
||
bufferLength = MAXWMPATH;
|
||
}
|
||
*buffer = '\0';
|
||
|
||
/* Get our current resource class */
|
||
|
||
if (MwmBehavior)
|
||
{
|
||
res_class = WM_RESOURCE_CLASS;
|
||
}
|
||
else
|
||
{
|
||
res_class = DT_WM_RESOURCE_CLASS;
|
||
}
|
||
|
||
strcpy(screenName, "*");
|
||
strcat(screenName,XtName (pWS->pSD->screenTopLevelW));
|
||
|
||
/* construct and write out the resources specification */
|
||
|
||
if (flags & WM_RES_BACKDROP_IMAGE)
|
||
{
|
||
iLen = (strlen (res_class) + strlen (screenName) +
|
||
strlen (pWS->name) + strlen (WmNbackdrop) +
|
||
strlen (WmNimage) + strlen (pWS->backdrop.image) + 20);
|
||
|
||
if (iLen > bufferLength)
|
||
{
|
||
bufferLength += iLen;
|
||
buffer = (char *)
|
||
XtRealloc (buffer, bufferLength * sizeof(char));
|
||
}
|
||
|
||
sprintf (buffer, "%s%s*%s*%s*%s: %s\n", res_class,
|
||
screenName, pWS->name,
|
||
WmNbackdrop, WmNimage, pWS->backdrop.image);
|
||
|
||
AddStringToResourceData (buffer, &data, &cum_len);
|
||
}
|
||
|
||
if (flags & WM_RES_BACKDROP_IMAGETYPE)
|
||
{
|
||
iLen = (strlen (res_class) + strlen (screenName) +
|
||
strlen (pWS->name) + strlen (WmNbackdrop) +
|
||
strlen (WmNimageType) + 22);
|
||
|
||
if (iLen > bufferLength)
|
||
{
|
||
bufferLength += iLen;
|
||
buffer = (char *)
|
||
XtRealloc (buffer, bufferLength * sizeof(char));
|
||
}
|
||
|
||
sprintf (buffer, "%s%s*%s*%s*%s: %d\n", res_class,
|
||
screenName, pWS->name,
|
||
WmNbackdrop, WmNimageType, pWS->backdrop.imageType);
|
||
|
||
AddStringToResourceData (buffer, &data, &cum_len);
|
||
}
|
||
|
||
if (flags & WM_RES_WORKSPACE_TITLE)
|
||
{
|
||
String asciiName;
|
||
|
||
asciiName = WmXmStringToString (pWS->title);
|
||
|
||
iLen = strlen (res_class) + strlen (screenName) +
|
||
strlen (pWS->name) + strlen (WmNtitle) +
|
||
strlen (asciiName) + 16;
|
||
|
||
if (iLen > bufferLength)
|
||
{
|
||
bufferLength += iLen;
|
||
buffer = (char *)
|
||
XtRealloc (buffer, bufferLength * sizeof(char));
|
||
}
|
||
|
||
sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
|
||
screenName, pWS->name,
|
||
WmNtitle, asciiName);
|
||
|
||
AddStringToResourceData (buffer, &data, &cum_len);
|
||
|
||
XtFree (asciiName);
|
||
}
|
||
|
||
if ((flags & WM_RES_INITIAL_WORKSPACE) &&
|
||
(!wmGD.useStandardBehavior))
|
||
{
|
||
iLen = strlen (res_class) + strlen (screenName) +
|
||
strlen (WmNinitialWorkspace) + strlen (pWS->name) + 14;
|
||
|
||
if (iLen > bufferLength)
|
||
{
|
||
bufferLength += iLen;
|
||
buffer = (char *)
|
||
XtRealloc (buffer, bufferLength * sizeof(char));
|
||
}
|
||
|
||
sprintf (buffer, "%s%s*%s: %s\n", res_class,
|
||
screenName,
|
||
WmNinitialWorkspace, pWS->name);
|
||
|
||
AddStringToResourceData (buffer, &data, &cum_len);
|
||
}
|
||
|
||
if ((flags & WM_RES_WORKSPACE_LIST) &&
|
||
(!wmGD.useStandardBehavior))
|
||
{
|
||
WmWorkspaceData *pWSi;
|
||
char *pchQname;
|
||
int i;
|
||
|
||
pWSi = pWS->pSD->pWS;
|
||
|
||
pchQname = (char *) _DtWmParseMakeQuotedString (
|
||
(unsigned char *)pWSi->name);
|
||
strcpy ((char *)wmGD.tmpBuffer, pchQname);
|
||
XtFree (pchQname);
|
||
pWSi++;
|
||
|
||
|
||
for (i=1; i<pWS->pSD->numWorkspaces; i++, pWSi++)
|
||
{
|
||
strcat ((char *)wmGD.tmpBuffer, " ");
|
||
pchQname = (char *) _DtWmParseMakeQuotedString (
|
||
(unsigned char *)pWSi->name);
|
||
strcat ((char *)wmGD.tmpBuffer, pchQname);
|
||
XtFree (pchQname);
|
||
}
|
||
|
||
sprintf (buffer, "%s%s*%s: %s\n", res_class,
|
||
screenName,
|
||
WmNworkspaceList, wmGD.tmpBuffer);
|
||
|
||
AddStringToResourceData (buffer, &data, &cum_len);
|
||
}
|
||
|
||
if ((flags & WM_RES_WORKSPACE_COUNT) &&
|
||
(!wmGD.useStandardBehavior))
|
||
{
|
||
char pchNumWs[20];
|
||
|
||
sprintf (pchNumWs, "%d", pWS->pSD->numWorkspaces);
|
||
|
||
iLen = strlen (res_class) + strlen (screenName) +
|
||
strlen (WmNworkspaceCount) + strlen (pchNumWs) + 14;
|
||
|
||
if (iLen > bufferLength)
|
||
{
|
||
bufferLength += iLen;
|
||
buffer = (char *)
|
||
XtRealloc (buffer, bufferLength * sizeof(char));
|
||
}
|
||
|
||
sprintf (buffer, "%s%s*%s: %s\n", res_class,
|
||
screenName,
|
||
WmNworkspaceCount, pchNumWs);
|
||
|
||
AddStringToResourceData (buffer, &data, &cum_len);
|
||
}
|
||
|
||
if ((flags & WM_RES_FP_POSITION) &&
|
||
(O_Shell(pPanelist)) &&
|
||
(!wmGD.useStandardBehavior) &&
|
||
(!XFindContext (DISPLAY, XtWindow(O_Shell(pPanelist)),
|
||
wmGD.windowContextType,
|
||
(XtPointer)&pCD_Panel)))
|
||
{
|
||
Position midX, midY, tmpX, tmpY;
|
||
Dimension screenWidth, screenHeight;
|
||
|
||
clientX = pCD_Panel->clientX;
|
||
clientY = pCD_Panel->clientY;
|
||
|
||
/*
|
||
* Determine quadrant that the front panel midpoint is
|
||
* in and save front panel with appropriate gravity.
|
||
*/
|
||
|
||
/* find panel midpoint */
|
||
|
||
midX = clientX+(pCD_Panel->clientWidth >> 1);
|
||
midY = clientY+(pCD_Panel->clientHeight >> 1);
|
||
|
||
/* get screen dimensions */
|
||
|
||
screenWidth = XDisplayWidth (DISPLAY, pCD_Panel->pSD->screen);
|
||
screenHeight = XDisplayHeight (DISPLAY, pCD_Panel->pSD->screen);
|
||
|
||
/*
|
||
* Determine midpoint quadrant and set up client geometry
|
||
* relative to that corner. Adjust if positionIsFrame
|
||
* is being used.
|
||
*/
|
||
if (midX <= (Position) screenWidth/2)
|
||
{
|
||
if(wmGD.positionIsFrame)
|
||
{
|
||
clientX -= pCD_Panel->frameInfo.upperBorderWidth;
|
||
}
|
||
|
||
/* West */
|
||
if (midY <= (Position) screenHeight/2)
|
||
{
|
||
/* NorthWest */
|
||
if(wmGD.positionIsFrame)
|
||
{
|
||
clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
|
||
pCD_Panel->frameInfo.titleBarHeight);
|
||
}
|
||
sprintf (tmpBuffer, "+%d+%d", clientX, clientY);
|
||
}
|
||
else
|
||
{
|
||
/* SouthWest */
|
||
clientY = screenHeight - clientY - pCD_Panel->clientHeight;
|
||
if(wmGD.positionIsFrame)
|
||
{
|
||
clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
|
||
}
|
||
|
||
sprintf (tmpBuffer, "+%d-%d", clientX, clientY);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
clientX = screenWidth - clientX - pCD_Panel->clientWidth;
|
||
if (wmGD.positionIsFrame)
|
||
{
|
||
clientX -= pCD_Panel->frameInfo.lowerBorderWidth;
|
||
}
|
||
|
||
/* East */
|
||
if (midY <= (Position) screenHeight/2)
|
||
{
|
||
/* NorthEast */
|
||
if(wmGD.positionIsFrame)
|
||
{
|
||
clientY -= (pCD_Panel->frameInfo.upperBorderWidth +
|
||
pCD_Panel->frameInfo.titleBarHeight);
|
||
}
|
||
sprintf (tmpBuffer, "-%d+%d", clientX, clientY);
|
||
}
|
||
else
|
||
{
|
||
/* SouthEast */
|
||
clientY = screenHeight - clientY - pCD_Panel->clientHeight;
|
||
if(wmGD.positionIsFrame)
|
||
{
|
||
clientY -= pCD_Panel->frameInfo.lowerBorderWidth;
|
||
}
|
||
sprintf (tmpBuffer, "-%d-%d", clientX, clientY);
|
||
}
|
||
}
|
||
|
||
iLen = strlen (res_class) + strlen (screenName) +
|
||
strlen (XtName(O_Shell(pPanelist))) +
|
||
strlen (WmNgeometry) + strlen (tmpBuffer) + 18;
|
||
|
||
if (iLen > bufferLength)
|
||
{
|
||
bufferLength += iLen;
|
||
buffer = (char *)
|
||
XtRealloc (buffer, bufferLength * sizeof(char));
|
||
}
|
||
|
||
sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
|
||
screenName,
|
||
XtName (O_Shell(pPanelist)),
|
||
WmNgeometry, tmpBuffer);
|
||
|
||
AddStringToResourceData (buffer, &data, &cum_len);
|
||
}
|
||
|
||
if ((flags & WM_RES_ICONBOX_GEOMETRY) &&
|
||
(!wmGD.useStandardBehavior))
|
||
{
|
||
/* update iconbox geometry string */
|
||
|
||
if (pWS->iconBoxGeometry)
|
||
{
|
||
XtFree((char *) (pWS->iconBoxGeometry));
|
||
pWS->iconBoxGeometry = NULL;
|
||
}
|
||
|
||
clientWidth = (pWS->pIconBox->pCD_iconBox->clientWidth -
|
||
pWS->pIconBox->pCD_iconBox->baseWidth) /
|
||
pWS->pIconBox->pCD_iconBox->widthInc;
|
||
|
||
clientHeight = (pWS->pIconBox->pCD_iconBox->clientHeight -
|
||
pWS->pIconBox->pCD_iconBox->baseHeight) /
|
||
pWS->pIconBox->pCD_iconBox->heightInc ;
|
||
|
||
if(wmGD.positionIsFrame)
|
||
{
|
||
CalculateGravityOffset (pWS->pIconBox->pCD_iconBox, &xoff, &yoff);
|
||
clientX = pWS->pIconBox->pCD_iconBox->clientX - xoff;
|
||
clientY = pWS->pIconBox->pCD_iconBox->clientY - yoff;
|
||
}
|
||
else
|
||
{
|
||
clientX = pWS->pIconBox->pCD_iconBox->clientX;
|
||
clientY = pWS->pIconBox->pCD_iconBox->clientY;
|
||
}
|
||
|
||
sprintf (buffer, "%dx%d+%d+%d", clientWidth, clientHeight,
|
||
clientX, clientY);
|
||
|
||
pWS->iconBoxGeometry = strdup( buffer);
|
||
|
||
iLen = strlen (res_class) + strlen (screenName) +
|
||
strlen (pWS->name) + strlen (WmNiconBoxGeometry) +
|
||
strlen (pWS->iconBoxGeometry) + 18;
|
||
|
||
if (iLen > bufferLength)
|
||
{
|
||
bufferLength += iLen;
|
||
buffer = (char *)
|
||
XtRealloc (buffer, bufferLength * sizeof(char));
|
||
}
|
||
|
||
sprintf (buffer, "%s%s*%s*%s: %s\n", res_class,
|
||
screenName, pWS->name,
|
||
WmNiconBoxGeometry, pWS->iconBoxGeometry);
|
||
|
||
AddStringToResourceData (buffer, &data, &cum_len);
|
||
}
|
||
|
||
|
||
if (data)
|
||
{
|
||
/*
|
||
* Merge in the resource(s)
|
||
*/
|
||
_DtAddToResource (DISPLAY, data);
|
||
XtFree(data);
|
||
}
|
||
|
||
XtFree(buffer);
|
||
|
||
} /* END OF FUNCTION SaveWorkspaceResources */
|
||
|
||
|
||
/******************************<->*************************************
|
||
*
|
||
* AddStringToResourceData (string, pdata, plen)
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Adds a string to a growing buffer of strings.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* string - string to add
|
||
* pdata - pointer to data pointer
|
||
* plen - number of bytes used in *pdata already
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* *pdata - data pointer (may be changed by XtRealloc)
|
||
* *plen - number of bytes used in *pdata (old value plus length
|
||
* of string
|
||
*
|
||
* Comments:
|
||
* ---------
|
||
*
|
||
*************************************<->***********************************/
|
||
void
|
||
AddStringToResourceData(
|
||
char *string,
|
||
char **pdata,
|
||
int *plen )
|
||
{
|
||
if ((*pdata = (char *) XtRealloc(*pdata, *plen+strlen(string)+1)) == NULL)
|
||
{
|
||
Warning (((char *)GETMESSAGE(76, 13, "Insufficient memory to save resources.")));
|
||
Do_Quit_Mwm (False);
|
||
}
|
||
|
||
strcat (*pdata, string);
|
||
*plen += strlen(string);
|
||
} /* END OF FUNCTION AddStringToResourceData */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* DuplicateWorkspaceName (pSD, name, num)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function searches the first "num" workspace names to see if the
|
||
* passed "name" duplicates any workspace name defined so far.
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pSD = pointer to screen data
|
||
* name = potential string name for workspace
|
||
* num = number of workspaces to check against
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* Return = True if a dupicate was found
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*
|
||
*************************************<->***********************************/
|
||
Boolean
|
||
DuplicateWorkspaceName (WmScreenData *pSD, unsigned char *name, int num)
|
||
{
|
||
int i;
|
||
Boolean duplicate = False;
|
||
|
||
if (pSD && pSD->pWS)
|
||
{
|
||
for (i = 0; (i < num) && !duplicate; i++)
|
||
{
|
||
if (!strcmp (pSD->pWS[i].name, (char *)name))
|
||
{
|
||
duplicate = True;
|
||
}
|
||
}
|
||
}
|
||
|
||
return (duplicate);
|
||
}
|
||
|
||
#ifdef DEBUG
|
||
int PrintWorkspaceList (pSD)
|
||
WmScreenData *pSD;
|
||
{
|
||
int i, j, k;
|
||
WmWorkspaceData *pWS;
|
||
ClientData *pCD;
|
||
ClientData *pClients[500];
|
||
int numSaved = 0;
|
||
Boolean Saved;
|
||
|
||
fprintf (stderr, "Screen: %d\n", pSD->screen);
|
||
|
||
for (i =0; i < pSD->numWorkspaces; i++)
|
||
{
|
||
pWS = &pSD->pWS[i];
|
||
|
||
fprintf (stderr, "\nWorkspace %s contains: \n", pWS->name);
|
||
|
||
for (j = 0; j < pWS->numClients; j++)
|
||
{
|
||
pCD = pWS->ppClients[j];
|
||
fprintf (stderr, "\t%s\n", pCD->clientName);
|
||
|
||
Saved = False;
|
||
for (k = 0; k < numSaved; k++)
|
||
{
|
||
if (pCD == pClients[k])
|
||
{
|
||
Saved = True;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!Saved)
|
||
{
|
||
pClients[numSaved++] = pCD;
|
||
}
|
||
}
|
||
}
|
||
|
||
for (i = 0; i < numSaved; i++)
|
||
{
|
||
pCD = pClients[i];
|
||
fprintf (stderr, "\nClient %s is in: \n", pCD->clientName);
|
||
for (j = 0; j < pCD->numInhabited; j++)
|
||
{
|
||
pWS = GetWorkspaceData (pCD->pSD, pCD->pWsList[j].wsID);
|
||
fprintf (stderr, "\t%s\n", pWS->name);
|
||
}
|
||
|
||
}
|
||
} /* END OF FUNCTION PrintWorkspaceList */
|
||
#endif /* DEBUG */
|
||
|