Blame clients/mwm/WmManage.c

Packit b099d7
/* 
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
*/ 
Packit b099d7
/* 
Packit b099d7
 * Motif Release 1.2.4
Packit b099d7
*/
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
 
Packit b099d7
#ifdef REV_INFO
Packit b099d7
#ifndef lint
Packit b099d7
static char rcsid[] = "$TOG: WmManage.c /main/11 1998/01/12 16:45:48 cshi $"
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
/*
Packit b099d7
 * (c) Copyright 1987, 1988, 1989, 1990, 1992, 1993 HEWLETT-PACKARD COMPANY 
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Included Files:
Packit b099d7
 */
Packit b099d7
Packit b099d7
#include "WmGlobal.h"
Packit b099d7
#include "WmICCC.h"
Packit b099d7
/*
Packit b099d7
 * include extern functions
Packit b099d7
 */
Packit b099d7
#include "WmCDecor.h"
Packit b099d7
#include "WmCEvent.h"
Packit b099d7
#include "WmColormap.h"
Packit b099d7
#include "WmError.h"
Packit b099d7
#include "WmEvent.h"
Packit b099d7
#include "WmFunction.h"
Packit b099d7
#include "WmGraphics.h"
Packit b099d7
#include "WmIDecor.h"
Packit b099d7
#include "WmIconBox.h"
Packit b099d7
#include "WmImage.h"
Packit b099d7
#include "WmKeyFocus.h"
Packit b099d7
#ifdef PANELIST
Packit b099d7
#include "WmPanelP.h"	/* typedef needed in WmManage.h */
Packit b099d7
#include 
Packit b099d7
#include "WmIPC.h"
Packit b099d7
#endif /* PANELIST */
Packit b099d7
#include "WmManage.h"
Packit b099d7
#include "WmMenu.h"
Packit b099d7
#include "WmProperty.h"
Packit b099d7
#include "WmProtocol.h"
Packit b099d7
#include "WmWinInfo.h"
Packit b099d7
#include "WmWinList.h"
Packit b099d7
#include "WmWinState.h"
Packit b099d7
#ifdef WSM
Packit b099d7
#include "WmPresence.h"
Packit b099d7
#include "WmWrkspace.h"
Packit b099d7
#endif /* WSM */
Packit b099d7
#include "WmXSMP.h"
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Function Declarations:
Packit b099d7
 */
Packit b099d7
Packit b099d7
#ifdef PANELIST
Packit b099d7
Packit b099d7
Boolean IsEmbeddedClient (
Packit b099d7
    ClientData *pCD, 
Packit b099d7
    WmFpEmbeddedClientData **ppECD);
Packit b099d7
Boolean ManageEmbeddedClient ( 
Packit b099d7
    ClientData *pCD, 
Packit b099d7
    WmFpEmbeddedClientData *pECD,
Packit b099d7
    long manageFlags);
Packit b099d7
Boolean IsPushRecallClient (
Packit b099d7
    ClientData *pCD, 
Packit b099d7
    WmFpPushRecallClientData **ppPRCD);
Packit b099d7
static void HandleSubstructEvents(
Packit b099d7
        Widget w,
Packit b099d7
        caddr_t ptr,
Packit b099d7
        XEvent *event );
Packit b099d7
Boolean UpdateEmbeddedClientsProperty(
Packit b099d7
        WmScreenData *pSD );
Packit b099d7
static void ForceSubpanelWMState(Window win);
Packit b099d7
static void ReManageWindow (ClientData *pCD);
Packit b099d7
static void CheckPushRecallClient (ClientData *pCD);
Packit b099d7
Packit b099d7
#endif /* PANELIST */
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Global Variables:
Packit b099d7
 */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  AdoptInitialClients (pSD)
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  -------
Packit b099d7
 *  pSD = pointer to screen data
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function is called to find client windows that were mapped prior to 
Packit b099d7
 *  starting (or restarting) the window manager.  These windows are included
Packit b099d7
 *  in the set of windows managed by the window manager.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void AdoptInitialClients (WmScreenData *pSD)
Packit b099d7
{
Packit b099d7
    Window  root;
Packit b099d7
    Window  parent;
Packit b099d7
    Window *clients;
Packit b099d7
#ifdef WSM
Packit b099d7
    int nAncillaries, iAnc;
Packit b099d7
    Window *pAncillaryWindows, *pWin1;
Packit b099d7
    WmWorkspaceData *pWS0;
Packit b099d7
#endif /* WSM */
Packit b099d7
    unsigned int     nclients;
Packit b099d7
    ClientData *pcd = NULL;
Packit b099d7
    PropWMState *wmStateProp;
Packit b099d7
    Boolean manageOnRestart;
Packit b099d7
    int i,j;
Packit b099d7
    long manageFlags;
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    /* 
Packit b099d7
     * Generate list of ancillary windows (not to be managed)
Packit b099d7
     */
Packit b099d7
    nAncillaries = 2 + pSD->numWorkspaces;
Packit b099d7
    pAncillaryWindows = (Window *) XtMalloc (sizeof(Window)*(nAncillaries));
Packit b099d7
    if (!pAncillaryWindows)
Packit b099d7
    {
Packit b099d7
	Warning (((char *)GETMESSAGE(46, 1, "Insufficient memory to adopt initial clients")));
Packit b099d7
	ExitWM (WM_ERROR_EXIT_VALUE);
Packit b099d7
    }
Packit b099d7
    pWS0 = pSD->pWS;
Packit b099d7
    pWin1 = pAncillaryWindows;
Packit b099d7
    for (iAnc = 0; iAnc < pSD->numWorkspaces; iAnc++)
Packit b099d7
    {
Packit b099d7
	*pWin1 = XtWindow((pWS0)->workspaceTopLevelW);
Packit b099d7
	pWin1++;
Packit b099d7
	pWS0++;
Packit b099d7
    }
Packit b099d7
    *pWin1++ = XtWindow (pSD->screenTopLevelW);
Packit b099d7
    *pWin1 = pSD->activeIconTextWin;
Packit b099d7
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Look for mapped top-level windows and start managing them:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (XQueryTree (DISPLAY, pSD->rootWindow, &root, &parent, &clients,
Packit b099d7
	    &nclients))
Packit b099d7
    {
Packit b099d7
#ifndef DONT_FILTER_ICON_WINDOWS
Packit b099d7
	/*
Packit b099d7
	 * Filter out icon windows so they don't get managed as a client
Packit b099d7
	 * window.  Icon windows will be process in SetupClientIconWindow().
Packit b099d7
	 */
Packit b099d7
	XWMHints *tmphint;
Packit b099d7
Packit b099d7
	for (i = 0; i < nclients; i++) {
Packit b099d7
	    if (clients[i]) {
Packit b099d7
		if ((tmphint = XGetWMHints (DISPLAY, clients[i])) != NULL) {
Packit b099d7
		    if (tmphint->flags & IconWindowHint) {
Packit b099d7
			for (j = 0; j < nclients; j++) {
Packit b099d7
			    if (clients[j] == tmphint->icon_window) {
Packit b099d7
				clients[j] = None;
Packit b099d7
				break;
Packit b099d7
			    }
Packit b099d7
			}
Packit b099d7
		    }
Packit b099d7
		    XFree ((char *) tmphint);
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
#endif
Packit b099d7
Packit b099d7
	for (i = 0; i < nclients; i++)
Packit b099d7
	{
Packit b099d7
	    /* determine if the client window should be managed by wm */
Packit b099d7
#ifdef WSM
Packit b099d7
            if (InWindowList (clients[i], pAncillaryWindows, nAncillaries))
Packit b099d7
            {
Packit b099d7
		/* don't manage ancillary window manager windows */
Packit b099d7
                continue;
Packit b099d7
	    }
Packit b099d7
#else /* WSM */
Packit b099d7
            if ((clients[i] == XtWindow (pSD->screenTopLevelW)) ||
Packit b099d7
		(clients[i] == XtWindow (pSD->pActiveWS->workspaceTopLevelW)) ||
Packit b099d7
		(clients[i] == pSD->activeIconTextWin))
Packit b099d7
            {
Packit b099d7
		/* don't manage ancillary window manager windows */
Packit b099d7
                continue;
Packit b099d7
	    }
Packit b099d7
#endif /* WSM */
Packit b099d7
	    if (!XFindContext (DISPLAY, clients[i], wmGD.windowContextType,
Packit b099d7
	        (caddr_t *)&pcd)) 
Packit b099d7
	    {
Packit b099d7
		/* don't manage a window we've already established a 
Packit b099d7
		   context for (e.g. icon windows) */
Packit b099d7
		continue;
Packit b099d7
	    }
Packit b099d7
	    if (!WmGetWindowAttributes (clients[i]))
Packit b099d7
            {
Packit b099d7
		/* can't access the window; ignore it */
Packit b099d7
		continue;
Packit b099d7
            }
Packit b099d7
	    /* window attributes are put into the global cache */
Packit b099d7
Packit b099d7
	    /*
Packit b099d7
	     * Get the window WM_STATE property value to determine the
Packit b099d7
	     * initial window state if the wm is being restarted.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    manageFlags = MANAGEW_WM_STARTUP;
Packit b099d7
	    manageOnRestart = True;
Packit b099d7
Packit b099d7
	    if (wmGD.wmRestarted)
Packit b099d7
	    {
Packit b099d7
		manageFlags |= MANAGEW_WM_RESTART;
Packit b099d7
		if ((wmStateProp = GetWMState (clients[i])) != NULL)
Packit b099d7
		{
Packit b099d7
		    if (wmStateProp->state == IconicState)
Packit b099d7
		    {
Packit b099d7
			manageFlags |= MANAGEW_WM_RESTART_ICON;
Packit b099d7
		    }
Packit b099d7
		    else if (wmStateProp->state != NormalState)
Packit b099d7
		    {
Packit b099d7
			manageOnRestart = False;
Packit b099d7
		    }
Packit b099d7
		    XFree ((char *)wmStateProp);
Packit b099d7
		}
Packit b099d7
		else 
Packit b099d7
		{
Packit b099d7
		    manageOnRestart = False;
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
Packit b099d7
	    /*
Packit b099d7
	     * Don't manage any override_redirect windows (mapped or not).
Packit b099d7
	     * Manage an unmapped window if it has a WM_STATE property
Packit b099d7
	     *   and it is not Withdrawn.
Packit b099d7
	     * Manage any window that is mapped.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    if ((wmGD.windowAttributes.override_redirect != True) &&
Packit b099d7
		((wmGD.wmRestarted && manageOnRestart) ||
Packit b099d7
		 (wmGD.windowAttributes.map_state != IsUnmapped)))
Packit b099d7
	    {
Packit b099d7
		ManageWindow (pSD, clients[i], manageFlags);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (nclients)
Packit b099d7
	{
Packit b099d7
	    XFree ((char *)clients);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    if (pAncillaryWindows)
Packit b099d7
    {
Packit b099d7
	XtFree ((char *) pAncillaryWindows);
Packit b099d7
    }
Packit b099d7
#endif /* WSM  */
Packit b099d7
Packit b099d7
} /* END OF FUNCTION AdoptInitialClients */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ManageWindow (pSD, clientWindow, manageFlags)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This is the highlevel function that is used to include a window in
Packit b099d7
 *  the set of windows that are managed by the window manager.  The window
Packit b099d7
 *  gets reparented and decorated, gets an icon, is setup for window
Packit b099d7
 *  management event handling, etc.  Client windows that are controlled
Packit b099d7
 *  by the window manager (e.g., the icon box) are also managed with
Packit b099d7
 *  this function.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  clientWindow = window of the client that we should manage
Packit b099d7
 *
Packit b099d7
 *  manageFlags	= additional control information 
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  pCD = initialized client data
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void 
Packit b099d7
ManageWindow (WmScreenData *pSD, Window clientWindow, long manageFlags)
Packit b099d7
{
Packit b099d7
    ClientData *pCD;
Packit b099d7
    int initialState;
Packit b099d7
    int i;
Packit b099d7
    Boolean sendConfigNotify;
Packit b099d7
#ifdef WSM
Packit b099d7
    WmWorkspaceData *pwsi;
Packit b099d7
#endif /* WSM */
Packit b099d7
#ifdef PANELIST 
Packit b099d7
    WmFpEmbeddedClientData *pECD;
Packit b099d7
#endif /* PANELIST */
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Get client information including window attributes and window
Packit b099d7
     * property values.  Use this information to determine how the window
Packit b099d7
     * is to be managed.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!(pCD = GetClientInfo (pSD, clientWindow, manageFlags)))
Packit b099d7
    {
Packit b099d7
	/* error getting client info; do not manage the client window */
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
#ifdef PANELIST
Packit b099d7
    /*
Packit b099d7
     *  Handle case of transients that derive from embedded clients.
Packit b099d7
     */
Packit b099d7
    if (wmGD.dtSD && (wmGD.dtSD == pCD->pSD))
Packit b099d7
    {
Packit b099d7
	if (pCD->transientLeader && pCD->transientLeader->pECD)
Packit b099d7
	{
Packit b099d7
	    WmPanelistObject  pPanelist;
Packit b099d7
	    ClientData *pCDfp = NULL;
Packit b099d7
Packit b099d7
	    pPanelist = (WmPanelistObject) pCD->pSD->wPanelist;
Packit b099d7
	    (void) XFindContext (DISPLAY, XtWindow(O_Shell (pPanelist)),
Packit b099d7
		      wmGD.windowContextType, (caddr_t *)&pCDfp);
Packit b099d7
Packit b099d7
	    pCD->transientLeader = pCDfp;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (IsEmbeddedClient (pCD, &pECD))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * This client is embedded in the front panel 
Packit b099d7
	 */
Packit b099d7
	
Packit b099d7
	if (ManageEmbeddedClient(pCD, pECD, manageFlags))
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     *   ...then we've embedded it in the front
Packit b099d7
	     *   panel--no further processing required.
Packit b099d7
	     */
Packit b099d7
#ifdef WSM
Packit b099d7
	    if (smAckState == SM_START_ACK)
Packit b099d7
	    {
Packit b099d7
		SendClientMsg( wmGD.dtSmWindow, 
Packit b099d7
			      (long) wmGD.xa_DT_SM_WM_PROTOCOL,
Packit b099d7
			      (long) wmGD.xa_DT_WM_WINDOW_ACK,
Packit b099d7
			      CurrentTime, NULL, 0);
Packit b099d7
	    }
Packit b099d7
#endif /* WSM */
Packit b099d7
	    return;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    /*
Packit b099d7
     *  Handle case of transients that derive from embedded clients.
Packit b099d7
     *  !!!!
Packit b099d7
     */
Packit b099d7
#if 0
Packit b099d7
    if (pCD->transientLeader && pCD->transientLeader->pAccessPanel)
Packit b099d7
    {
Packit b099d7
        pCD->transientLeader = 
Packit b099d7
	    pCD->transientLeader->pAccessPanel->pCD_accessPanel;
Packit b099d7
    }
Packit b099d7
#endif 
Packit b099d7
#endif /* PANELIST */
Packit b099d7
#ifdef WSM
Packit b099d7
    if (pCD->inputMode == MWM_INPUT_SYSTEM_MODAL)
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * Put system modal windows in all workspaces to
Packit b099d7
	 * avoid the race condition of the window coming up
Packit b099d7
	 * just as the user switches workspaces.
Packit b099d7
	 */
Packit b099d7
	pCD->dtwmFunctions |= DtWM_FUNCTION_OCCUPY_WS;
Packit b099d7
	F_AddToAllWorkspaces(0, pCD, 0);
Packit b099d7
	pCD->dtwmFunctions &= ~DtWM_FUNCTION_OCCUPY_WS;
Packit b099d7
    }
Packit b099d7
#endif /* WSM */
Packit b099d7
    if (manageFlags & MANAGEW_WM_RESTART)
Packit b099d7
    {
Packit b099d7
	if (manageFlags & MANAGEW_WM_RESTART_ICON)
Packit b099d7
	{
Packit b099d7
	    pCD->clientState = MINIMIZED_STATE;
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    pCD->clientState = NORMAL_STATE;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Setup the initial placement of the client window.  Do interactive
Packit b099d7
     * placement if configured.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    sendConfigNotify = InitClientPlacement (pCD, manageFlags);
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Make a window frame for the client window and reparent the client
Packit b099d7
     * window.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!FrameWindow (pCD))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * Error in framing the window; clean up the wm resources made
Packit b099d7
	 * up to this point for the client window. Do not manage the
Packit b099d7
	 * client window.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	UnManageWindow (pCD);
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Send config notify if the client's been moved/resized
Packit b099d7
     */
Packit b099d7
    if (sendConfigNotify)
Packit b099d7
    {
Packit b099d7
	SendConfigureNotify (pCD);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Send client offset message if:
Packit b099d7
     *
Packit b099d7
     *   1. The client is interested.
Packit b099d7
     *   2. The position we report to the user is not the client's real
Packit b099d7
     *      position.
Packit b099d7
     *   3. There is a client offset to report.
Packit b099d7
     */
Packit b099d7
    if ((pCD->protocolFlags & PROTOCOL_MWM_OFFSET) &&
Packit b099d7
	(wmGD.positionIsFrame) && 
Packit b099d7
	((pCD->clientOffset.x != 0) ||
Packit b099d7
	 (pCD->clientOffset.y != 0)))
Packit b099d7
    { 
Packit b099d7
	SendClientOffsetMessage (pCD);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Make an icon for the client window if it is not a valid transient
Packit b099d7
     * window.
Packit b099d7
     */
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    if ((pCD->clientFunctions & MWM_FUNC_MINIMIZE) &&
Packit b099d7
	(pCD->transientLeader == NULL))
Packit b099d7
    {
Packit b099d7
	/* 
Packit b099d7
	 * Make icons frames 
Packit b099d7
	 * Only make one icon frame for root icons.
Packit b099d7
	 * Make one per workspace for icon box icons.
Packit b099d7
	 */
Packit b099d7
	for (i = 0; i < pCD->numInhabited; i++)
Packit b099d7
	{
Packit b099d7
	    if (pwsi = GetWorkspaceData(pCD->pSD, pCD->pWsList[i].wsID))
Packit b099d7
	    {
Packit b099d7
Packit b099d7
		if ((pCD->pSD->useIconBox && 
Packit b099d7
                     !(manageFlags & MANAGEW_WM_CLIENTS) &&
Packit b099d7
		     !(pCD->clientFlags & FRONT_PANEL_BOX)) || (i == 0))
Packit b099d7
		{
Packit b099d7
		    /*
Packit b099d7
		     *   Make icon inside an icon box for non-root case
Packit b099d7
		     */
Packit b099d7
		    if (!MakeIcon (pwsi, pCD)) 
Packit b099d7
		    { 
Packit b099d7
			/*
Packit b099d7
			 * Error in making an icon for the client window; 
Packit b099d7
			 * clean up the wm resources; do not manage the 
Packit b099d7
			 * client window.
Packit b099d7
			 */
Packit b099d7
Packit b099d7
			UnManageWindow (pCD);
Packit b099d7
			return;
Packit b099d7
		    }
Packit b099d7
		    else 
Packit b099d7
		    {
Packit b099d7
			XSaveContext (DISPLAY, pCD->pWsList[i].iconFrameWin, 
Packit b099d7
				wmGD.windowContextType, (caddr_t)pCD);
Packit b099d7
Packit b099d7
			if (pCD->iconWindow && pCD->pWsList[i].iconFrameWin)
Packit b099d7
			{
Packit b099d7
			    XGrabButton (DISPLAY, AnyButton, AnyModifier, 
Packit b099d7
				pCD->pWsList[i].iconFrameWin, True,
Packit b099d7
				ButtonPressMask|ButtonReleaseMask|
Packit b099d7
				    ButtonMotionMask,
Packit b099d7
				GrabModeAsync, GrabModeAsync, None, 
Packit b099d7
				wmGD.workspaceCursor);
Packit b099d7
			}
Packit b099d7
		    }
Packit b099d7
		}
Packit b099d7
		else 
Packit b099d7
		{
Packit b099d7
		    /* 
Packit b099d7
		     *  Make root icons for a client
Packit b099d7
		     */
Packit b099d7
 		    if ((pCD->clientFunctions & MWM_FUNC_MINIMIZE) &&
Packit b099d7
 			(pCD->transientLeader == NULL))
Packit b099d7
 		    {
Packit b099d7
 			if ((i == 0) &&
Packit b099d7
 			    (!MakeIcon (pwsi, pCD)))
Packit b099d7
 			{
Packit b099d7
 			    /*
Packit b099d7
 			     * Error in making an icon for the client 
Packit b099d7
 			     * window; clean up the wm resources; do 
Packit b099d7
 			     * not manage the client window.
Packit b099d7
 			     */
Packit b099d7
 
Packit b099d7
 			    UnManageWindow (pCD);
Packit b099d7
 			    return;
Packit b099d7
 			}
Packit b099d7
 			else
Packit b099d7
 			{
Packit b099d7
 			    /* copy root icon frame reference to other 
Packit b099d7
 			     * workspaces
Packit b099d7
			     */
Packit b099d7
 			    pCD->pWsList[i].iconFrameWin = 
Packit b099d7
 				    pCD->pWsList[0].iconFrameWin;
Packit b099d7
 			}
Packit b099d7
 		    }
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
#else /* WSM */
Packit b099d7
    if ((pCD->clientFunctions & MWM_FUNC_MINIMIZE) &&
Packit b099d7
        (pCD->transientLeader == NULL) && 
Packit b099d7
	  !MakeIcon (pCD->pSD->pActiveWS, pCD))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * Error in making an icon for the client window; clean up the wm
Packit b099d7
	 * resources; do not manage the client window.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	UnManageWindow (pCD);
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Register window contexts to facilitate event handling:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    XSaveContext (DISPLAY, pCD->clientFrameWin, wmGD.windowContextType,
Packit b099d7
	(caddr_t)pCD);
Packit b099d7
Packit b099d7
    XSaveContext (DISPLAY, pCD->clientBaseWin, wmGD.windowContextType,
Packit b099d7
	(caddr_t)pCD);
Packit b099d7
Packit b099d7
    if (DECOUPLE_TITLE_APPEARANCE(pCD) && pCD->clientTitleWin)
Packit b099d7
    {
Packit b099d7
	/* 
Packit b099d7
	 * handle exposures on title bar if it has its own appearance
Packit b099d7
	 */
Packit b099d7
	XSaveContext (DISPLAY, pCD->clientTitleWin, wmGD.windowContextType,
Packit b099d7
	    (caddr_t)pCD);
Packit b099d7
    }
Packit b099d7
#ifndef WSM
Packit b099d7
    if (pCD->iconFrameWin)
Packit b099d7
    {
Packit b099d7
	XSaveContext (DISPLAY, pCD->iconFrameWin, wmGD.windowContextType,
Packit b099d7
	    (caddr_t)pCD);
Packit b099d7
    }
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
    if (pCD->clientCmapCount > 0)
Packit b099d7
    {
Packit b099d7
	for (i = 0; i < pCD->clientCmapCount; i++)
Packit b099d7
	{
Packit b099d7
	    if (pCD->cmapWindows[i] != pCD->client)
Packit b099d7
	    {
Packit b099d7
#ifndef	IBM_169380
Packit b099d7
		AddColormapWindowReference(pCD, pCD->cmapWindows[i]);
Packit b099d7
#else
Packit b099d7
	        XSaveContext (DISPLAY, pCD->cmapWindows[i],
Packit b099d7
		    wmGD.windowContextType, (caddr_t)pCD);
Packit b099d7
#endif
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    pCD->clientFlags |= CLIENT_CONTEXT_SAVED;
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Setup button binding handling for actions that apply to the client
Packit b099d7
     * window.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (BUTTON_SPECS(pCD))
Packit b099d7
    {
Packit b099d7
	SetupCButtonBindings (pCD->clientBaseWin, BUTTON_SPECS(pCD));
Packit b099d7
    }
Packit b099d7
Packit b099d7
#ifndef WSM
Packit b099d7
    if (pCD->iconWindow && pCD->iconFrameWin)
Packit b099d7
    {
Packit b099d7
	XGrabButton (DISPLAY, AnyButton, AnyModifier, pCD->iconFrameWin, True,
Packit b099d7
	    ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
Packit b099d7
	    GrabModeAsync, GrabModeAsync, None, wmGD.workspaceCursor);
Packit b099d7
    }
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Setup key binding handling for system menu accelerators.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (pCD->systemMenuSpec &&
Packit b099d7
        (pCD->systemMenuSpec->accelKeySpecs))
Packit b099d7
    {
Packit b099d7
	SetupKeyBindings (pCD->systemMenuSpec->accelKeySpecs,
Packit b099d7
			  pCD->clientFrameWin, GrabModeSync, F_CONTEXT_ALL);
Packit b099d7
#ifdef WSM
Packit b099d7
	for (i = 0; i < pCD->numInhabited; i++)
Packit b099d7
	{
Packit b099d7
	    if (!pCD->pWsList[i].pIconBox && pCD->pWsList[i].iconFrameWin)
Packit b099d7
	    {
Packit b099d7
		SetupKeyBindings (pCD->systemMenuSpec->accelKeySpecs,
Packit b099d7
			      pCD->pWsList[i].iconFrameWin, GrabModeSync, 
Packit b099d7
			      F_CONTEXT_ALL);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
#else /* WSM */
Packit b099d7
	if (!pCD->pIconBox && pCD->iconFrameWin)
Packit b099d7
	{
Packit b099d7
	    SetupKeyBindings (pCD->systemMenuSpec->accelKeySpecs,
Packit b099d7
			      pCD->iconFrameWin, GrabModeSync, F_CONTEXT_ALL);
Packit b099d7
	}
Packit b099d7
#endif /* WSM */
Packit b099d7
    }
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
  for (i = 0; i < pCD->numInhabited; i++)
Packit b099d7
  {
Packit b099d7
    if (!pCD->pWsList[i].pIconBox && pCD->pWsList[i].iconFrameWin)
Packit b099d7
#else /* WSM */
Packit b099d7
    if (!pCD->pIconBox && pCD->iconFrameWin)
Packit b099d7
#endif /* WSM */
Packit b099d7
    {
Packit b099d7
	static int iconKeySpec = 1;
Packit b099d7
	static int iconAccelSpec = 1;
Packit b099d7
Packit b099d7
        if ((iconKeySpec != 0) && KEY_SPECS(pCD))
Packit b099d7
        {
Packit b099d7
#ifdef WSM
Packit b099d7
	    iconKeySpec = SetupKeyBindings (KEY_SPECS(pCD), 
Packit b099d7
				pCD->pWsList[i].iconFrameWin,
Packit b099d7
				GrabModeSync, F_CONTEXT_ICON);
Packit b099d7
#else /* WSM */
Packit b099d7
	    iconKeySpec = SetupKeyBindings (KEY_SPECS(pCD), pCD->iconFrameWin,
Packit b099d7
				GrabModeSync, F_CONTEXT_ICON);
Packit b099d7
#endif /* WSM */
Packit b099d7
        }
Packit b099d7
Packit b099d7
        if ((iconAccelSpec != 0) && ACCELERATOR_MENU_COUNT(pCD))
Packit b099d7
        {
Packit b099d7
	    int n;
Packit b099d7
Packit b099d7
	    iconAccelSpec = 0;
Packit b099d7
	    for (n= 0; n < pSD->acceleratorMenuCount; n++)
Packit b099d7
	    {
Packit b099d7
#ifdef WSM
Packit b099d7
	        iconAccelSpec += SetupKeyBindings (
Packit b099d7
			    ACCELERATOR_MENU_SPECS(pCD)[n]->accelKeySpecs,
Packit b099d7
			    pCD->pWsList[i].iconFrameWin, GrabModeSync,
Packit b099d7
			    F_CONTEXT_ICON);
Packit b099d7
#else /* WSM */
Packit b099d7
	        iconAccelSpec += SetupKeyBindings (
Packit b099d7
			    ACCELERATOR_MENU_SPECS(pCD)[n]->accelKeySpecs,
Packit b099d7
			    pCD->iconFrameWin, GrabModeSync,
Packit b099d7
			    F_CONTEXT_ICON);
Packit b099d7
#endif /* WSM */
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
#ifdef WSM
Packit b099d7
  }
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Setup keyboard focus handling if policy is "explicit".
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT)
Packit b099d7
    {
Packit b099d7
	DoExplicitSelectGrab (pCD->clientBaseWin);
Packit b099d7
    }
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    UpdateWorkspacePresenceProperty(pCD);
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Make sure the client window has been reparented ...
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!(manageFlags & MANAGEW_WM_CLIENTS))
Packit b099d7
    {
Packit b099d7
        XSync (DISPLAY, False);
Packit b099d7
Packit b099d7
        if (pCD->clientFlags & CLIENT_DESTROYED)
Packit b099d7
        {
Packit b099d7
	    UnManageWindow (pCD);
Packit b099d7
	    return;
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Setup the initial display state for the client window:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    initialState = pCD->clientState;
Packit b099d7
#ifdef WSM
Packit b099d7
    if (!ClientInWorkspace (pSD->pActiveWS, pCD))
Packit b099d7
    {
Packit b099d7
	initialState |= UNSEEN_STATE;
Packit b099d7
    }
Packit b099d7
#endif /* WSM */
Packit b099d7
    pCD->clientState = WITHDRAWN_STATE;
Packit b099d7
    pCD->clientFlags &= ~WM_INITIALIZATION;
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    /* 
Packit b099d7
     * Add to stacking list using the client's zero'th workspace
Packit b099d7
     * instead of the current one because it may not be in 
Packit b099d7
     * the current one.
Packit b099d7
     */
Packit b099d7
    AddClientToList (GetWorkspaceData (pSD, pCD->pWsList[0].wsID),
Packit b099d7
	pCD, True /*on top*/);
Packit b099d7
#else /* WSM */
Packit b099d7
    AddClientToList (pSD->pActiveWS, pCD, True /*on top*/);
Packit b099d7
#endif /* WSM */
Packit b099d7
    SetClientState (pCD, initialState, GetTimestamp());
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Set the keyboard input focus to the newly managed window if appropriate:
Packit b099d7
     * - focus is automatically set only if the focus policy is explicit
Packit b099d7
     * - if there is a system modal window active then set the focus only
Packit b099d7
     *   if the new window is in the system modal heirarchy
Packit b099d7
     * - focus is automatically set if startupKeyFocus is selected or
Packit b099d7
     *   the new window is a system modal window or the current focus window
Packit b099d7
     *   has the new window as an application modal subordinate
Packit b099d7
     * - don't automatically set the focus if the window is minimized or
Packit b099d7
     *   is a window that generally doesn't take input
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
Packit b099d7
	((pCD->inputMode == MWM_INPUT_SYSTEM_MODAL) ||
Packit b099d7
	 ((!wmGD.systemModalActive ||
Packit b099d7
	   (wmGD.systemModalClient == FindTransientTreeLeader (pCD))) &&
Packit b099d7
	  (wmGD.startupKeyFocus ||
Packit b099d7
	   (wmGD.keyboardFocus && (IS_APP_MODALIZED(wmGD.keyboardFocus)))) &&
Packit b099d7
	  !(manageFlags &
Packit b099d7
	    (MANAGEW_WM_STARTUP | MANAGEW_WM_RESTART | MANAGEW_WM_CLIENTS)) &&
Packit b099d7
	  (pCD->clientState != MINIMIZED_STATE) &&
Packit b099d7
#ifdef WSM
Packit b099d7
          !(pCD->clientState & UNSEEN_STATE) &&
Packit b099d7
#endif /* WSM */
Packit b099d7
	  (pCD->inputFocusModel ||
Packit b099d7
	   (pCD->protocolFlags & PROTOCOL_WM_TAKE_FOCUS)))))
Packit b099d7
    {
Packit b099d7
	Do_Focus_Key (pCD, GetTimestamp() , ALWAYS_SET_FOCUS);
Packit b099d7
    }
Packit b099d7
    else if ((pCD->inputMode == MWM_INPUT_SYSTEM_MODAL) ||
Packit b099d7
	     (wmGD.keyboardFocus && IS_APP_MODALIZED(wmGD.keyboardFocus)))
Packit b099d7
    {
Packit b099d7
	Do_Focus_Key ((ClientData *)NULL, GetTimestamp() , ALWAYS_SET_FOCUS);
Packit b099d7
    }
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    if (smAckState == SM_START_ACK)
Packit b099d7
    {
Packit b099d7
	SendClientMsg( wmGD.dtSmWindow, (long) wmGD.xa_DT_SM_WM_PROTOCOL,
Packit b099d7
		      (long) wmGD.xa_DT_WM_WINDOW_ACK,
Packit b099d7
		      CurrentTime, NULL, 0);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Free the initial property list. This will force
Packit b099d7
     * reads of properties that change after the initial
Packit b099d7
     * management (see HasProperty() function.)
Packit b099d7
     */
Packit b099d7
    DiscardInitialPropertyList (pCD);
Packit b099d7
Packit b099d7
#endif /* WSM */
Packit b099d7
#ifdef PANELIST
Packit b099d7
    CheckPushRecallClient (pCD);
Packit b099d7
#endif /* PANELIST */
Packit b099d7
Packit b099d7
} /* END OF FUNCTION ManageWindow */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  UnManageWindow (pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function removes a top-level client window and it's transients
Packit b099d7
 *  from the set of windows that is managed by the window manager.  
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD 	- pointer to client data of window to unmanage
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void UnManageWindow (ClientData *pCD)
Packit b099d7
{
Packit b099d7
#ifdef PANELIST
Packit b099d7
    if (pCD->pECD)
Packit b099d7
    {
Packit b099d7
	WmFpEmbeddedClientData *pECD;
Packit b099d7
Packit b099d7
	pECD = (WmFpEmbeddedClientData *) pCD->pECD;
Packit b099d7
Packit b099d7
	XtRemoveEventHandler(XtWindowToWidget (DISPLAY1, pECD->winParent),
Packit b099d7
		(SubstructureRedirectMask | SubstructureNotifyMask),
Packit b099d7
	        False,
Packit b099d7
		(XtEventHandler)HandleSubstructEvents,
Packit b099d7
		(XtPointer)(pCD));
Packit b099d7
Packit b099d7
	pECD->pCD = NULL;
Packit b099d7
	UpdateEmbeddedClientsProperty (pCD->pSD);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (pCD->pPRCD)
Packit b099d7
    {
Packit b099d7
	WmFpPushRecallClientData *pPRCD;
Packit b099d7
	int j;
Packit b099d7
Packit b099d7
	pPRCD = (WmFpPushRecallClientData *) pCD->pSD->pPRCD;
Packit b099d7
Packit b099d7
	for (j = 0; 
Packit b099d7
		 j < pCD->pSD->numPushRecallClients; 
Packit b099d7
			 j++, pPRCD++)
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Clean out all slots used by this client.
Packit b099d7
	     */
Packit b099d7
	    if ((!strcmp ((char *)pCD->clientName, 
Packit b099d7
			 (char *)(pPRCD->pchResName))) &&
Packit b099d7
		(pPRCD->pCD == pCD))
Packit b099d7
	    {
Packit b099d7
		pPRCD->pCD = NULL;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	pCD->pPRCD = NULL;
Packit b099d7
    }
Packit b099d7
#endif /* PANELIST */
Packit b099d7
    /*
Packit b099d7
     * Withdraw all the transient children of this window.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (pCD->transientChildren != NULL) 
Packit b099d7
    {
Packit b099d7
	WithdrawTransientChildren (pCD);
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * If this is a transient window, then delete it from the leader's
Packit b099d7
     * list of transients.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (pCD->transientLeader)
Packit b099d7
    {
Packit b099d7
	DeleteTransient (pCD);
Packit b099d7
Packit b099d7
        /* If this was a modal dialog box, then replay the event. */
Packit b099d7
        if ( wmGD.replayEnterEvent )
Packit b099d7
          {
Packit b099d7
            XPutBackEvent( DISPLAY, (XEvent*)&wmGD.savedEnterEvent );
Packit b099d7
            /* Reset event flag to false */
Packit b099d7
            wmGD.replayEnterEvent = False;
Packit b099d7
          }
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Withdraw this window
Packit b099d7
     */
Packit b099d7
Packit b099d7
    WithdrawWindow (pCD);
Packit b099d7
Packit b099d7
} /* END OF FUNCTION UnManageWindow */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  WithdrawTransientChildren (pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function withdraws all transient children of the specified window.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD = pointer to client data of the leader of the transient tree.
Packit b099d7
 * 
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void WithdrawTransientChildren (ClientData *pCD)
Packit b099d7
{
Packit b099d7
    ClientData *pcdNext;
Packit b099d7
    ClientData *pcdThis;
Packit b099d7
Packit b099d7
Packit b099d7
    pcdNext = pCD->transientChildren;
Packit b099d7
    while (pcdNext)
Packit b099d7
    {
Packit b099d7
	if (pcdNext->transientChildren)
Packit b099d7
	{
Packit b099d7
	    WithdrawTransientChildren (pcdNext);
Packit b099d7
	}
Packit b099d7
	pcdThis = pcdNext;
Packit b099d7
	pcdNext = pcdThis->transientSiblings;
Packit b099d7
	DeleteTransient(pcdThis);
Packit b099d7
	WithdrawWindow (pcdThis);
Packit b099d7
    }
Packit b099d7
Packit b099d7
} /* END OF FUNCTION WithdrawTransientChildren */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  WithdrawWindow (pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function removes a top-level client window from the set of windows
Packit b099d7
 *  that is managed by the window manager.  All window manager resources
Packit b099d7
 *  associtated with the client window are freed up (possibly cached for
Packit b099d7
 *  reuse).  Any custom system menu is destroyed.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD 	- pointer to client data of window to withdraw
Packit b099d7
 * 
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void WithdrawWindow (ClientData *pCD)
Packit b099d7
{
Packit b099d7
    int x;
Packit b099d7
    int y;
Packit b099d7
    int i;
Packit b099d7
    XWindowChanges xwc;
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Put the client window into a withdrawn state:
Packit b099d7
     *
Packit b099d7
     * - remove the icon/client window from the screen
Packit b099d7
     * - make sure the input focus no longer is associted with the window
Packit b099d7
     * - free the icon placement (if necessary)
Packit b099d7
     */
Packit b099d7
#ifdef WSM
Packit b099d7
    SetClientWsIndex (pCD);
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
    if (!(pCD->clientFlags & WM_INITIALIZATION))
Packit b099d7
    {
Packit b099d7
	if (!pCD->transientLeader)
Packit b099d7
	{
Packit b099d7
	    DeleteClientFromList (pCD->pSD->pActiveWS, pCD);
Packit b099d7
	}
Packit b099d7
	ResetWithdrawnFocii (pCD);
Packit b099d7
	if (pCD->clientState & MINIMIZED_STATE)
Packit b099d7
	{
Packit b099d7
#ifdef WSM
Packit b099d7
	    if (wmGD.iconAutoPlace && (!(P_ICON_BOX(pCD))))
Packit b099d7
	    {
Packit b099d7
		WmWorkspaceData *pWsTmp;
Packit b099d7
		WsClientData *pWsc;
Packit b099d7
		int j;
Packit b099d7
Packit b099d7
		/* 
Packit b099d7
		 * Clean up icon placement data in all inhabited
Packit b099d7
		 * workspaces
Packit b099d7
		 */
Packit b099d7
		for (j = 0; j< pCD->numInhabited; j++)
Packit b099d7
		{
Packit b099d7
		    pWsc = &(pCD->pWsList[j]);
Packit b099d7
Packit b099d7
		    if (pWsc->iconPlace != NO_ICON_PLACE)
Packit b099d7
		    {
Packit b099d7
			if (pWsTmp=GetWorkspaceData(pCD->pSD, pWsc->wsID))
Packit b099d7
			{
Packit b099d7
			  pWsTmp->IPData.placeList[pWsc->iconPlace].pCD 
Packit b099d7
			      = NULL;
Packit b099d7
			}
Packit b099d7
		    }
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
#else /* WSM */
Packit b099d7
	    if (wmGD.iconAutoPlace && (!(P_ICON_BOX(pCD))))
Packit b099d7
	    {
Packit b099d7
		if (ICON_PLACE(pCD) != NO_ICON_PLACE)
Packit b099d7
		{
Packit b099d7
		pCD->pSD->pActiveWS->IPData.placeList[ICON_PLACE(pCD)].pCD 
Packit b099d7
		    = NULL;
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
#endif /* WSM */
Packit b099d7
	    if (ICON_FRAME_WIN(pCD))
Packit b099d7
	    {
Packit b099d7
		XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
Packit b099d7
	    }
Packit b099d7
	    XFlush (DISPLAY);
Packit b099d7
	}
Packit b099d7
	else if ((pCD->clientState == NORMAL_STATE) ||
Packit b099d7
		 (pCD->clientState == MAXIMIZED_STATE))
Packit b099d7
	{
Packit b099d7
	    XUnmapWindow (DISPLAY, pCD->clientFrameWin);
Packit b099d7
	    XFlush (DISPLAY);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
#ifdef WSM
Packit b099d7
    /* 
Packit b099d7
     * Clean up the workspace presence dialog if it's
Packit b099d7
     * connected to this client.
Packit b099d7
     */
Packit b099d7
    if ((pCD->pSD->presence.shellW) &&
Packit b099d7
	(pCD->pSD->presence.pCDforClient == pCD))
Packit b099d7
    {
Packit b099d7
	if (pCD->pSD->presence.onScreen)
Packit b099d7
	{
Packit b099d7
	    HidePresenceBox (pCD->pSD, True);
Packit b099d7
	}
Packit b099d7
	pCD->pSD->presence.pCDforClient = NULL;
Packit b099d7
    }
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Check to see if the window is being unmanaged because the window
Packit b099d7
     * was destroyed.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!(pCD->clientFlags & CLIENT_DESTROYED))
Packit b099d7
    {
Packit b099d7
	XEvent eventReturn;
Packit b099d7
Packit b099d7
	if (XCheckTypedWindowEvent (DISPLAY, pCD->clientBaseWin, DestroyNotify,
Packit b099d7
	        &eventReturn))
Packit b099d7
	{
Packit b099d7
	    pCD->clientFlags |= CLIENT_DESTROYED;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Reparent the client window back to root if the window has been
Packit b099d7
     * reparented by the window manager.  Remove the window from the
Packit b099d7
     * window managers save-set if necessary.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if ((pCD->clientFlags & CLIENT_REPARENTED) &&
Packit b099d7
        !(pCD->clientFlags & CLIENT_DESTROYED))
Packit b099d7
    {
Packit b099d7
#ifdef WSM
Packit b099d7
	SetWMState (pCD->client, WithdrawnSTATE, 
Packit b099d7
		pCD->pWsList[0].iconFrameWin);
Packit b099d7
#else /* WSM */
Packit b099d7
	SetWMState (pCD->client, WithdrawnSTATE, ICON_FRAME_WIN(pCD));
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
	if (pCD->maxConfig)
Packit b099d7
	{
Packit b099d7
	    x = pCD->maxX;
Packit b099d7
	    y = pCD->maxY;
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    int xoff, yoff;
Packit b099d7
	    
Packit b099d7
	    if(wmGD.positionIsFrame)
Packit b099d7
            {
Packit b099d7
	      CalculateGravityOffset (pCD, &xoff, &yoff);
Packit b099d7
	      x = pCD->clientX - xoff;
Packit b099d7
	      y = pCD->clientY - yoff;
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	      {
Packit b099d7
	    x = pCD->clientX;
Packit b099d7
	    y = pCD->clientY;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
Packit b099d7
	XUnmapWindow (DISPLAY, pCD->client);
Packit b099d7
	XReparentWindow (DISPLAY, pCD->client, ROOT_FOR_CLIENT(pCD), x, y);
Packit b099d7
Packit b099d7
	/* give the window back it's X border */
Packit b099d7
	xwc.border_width = pCD->xBorderWidth;
Packit b099d7
	XConfigureWindow(DISPLAY, pCD->client, CWBorderWidth, &xwc;;
Packit b099d7
Packit b099d7
	if (pCD->iconWindow && (pCD->clientFlags & ICON_REPARENTED))
Packit b099d7
	{
Packit b099d7
	    XUnmapWindow (DISPLAY, pCD->iconWindow);
Packit b099d7
#ifdef WSM
Packit b099d7
	    XReparentWindow (DISPLAY, pCD->iconWindow, ROOT_FOR_CLIENT(pCD), 
Packit b099d7
			     pCD->pWsList[0].iconX, pCD->pWsList[0].iconY);
Packit b099d7
#else /* WSM */
Packit b099d7
	    XReparentWindow (DISPLAY, pCD->iconWindow, ROOT_FOR_CLIENT(pCD), 
Packit b099d7
			     ICON_X(pCD), ICON_Y(pCD));
Packit b099d7
#endif /* WSM */
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    if ((pCD->clientFlags & CLIENT_IN_SAVE_SET) &&
Packit b099d7
        !(pCD->clientFlags & CLIENT_DESTROYED))
Packit b099d7
    {
Packit b099d7
	XRemoveFromSaveSet (DISPLAY, pCD->client);
Packit b099d7
Packit b099d7
	if (pCD->iconWindow && (pCD->clientFlags & ICON_IN_SAVE_SET))
Packit b099d7
	{
Packit b099d7
	    XRemoveFromSaveSet (DISPLAY, pCD->iconWindow);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Free a custom system menu if one was created.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    FreeCustomMenuSpec (pCD->systemMenuSpec);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Free the client window frame:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (pCD->clientFrameWin)
Packit b099d7
    {
Packit b099d7
	FreeClientFrame (pCD);
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Free the icon associated with the client window:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (PIXMAP_IS_VALID( pCD->iconPixmap )) 
Packit b099d7
    {
Packit b099d7
	XFreePixmap (DISPLAY, pCD->iconPixmap);
Packit b099d7
    }
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    if ((pCD->numInhabited > 0) && ICON_FRAME_WIN(pCD))
Packit b099d7
#else /* WSM */
Packit b099d7
    if (ICON_FRAME_WIN(pCD))
Packit b099d7
#endif /* WSM */
Packit b099d7
    {
Packit b099d7
        FreeIcon (pCD);
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Free up the client protocol list:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (pCD->clientProtocols)
Packit b099d7
    {
Packit b099d7
	XtFree ((char *)pCD->clientProtocols);
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Free up the mwm messages list:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (pCD->mwmMessages)
Packit b099d7
    {
Packit b099d7
	XtFree ((char *)pCD->mwmMessages);
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Delete client window manager timers:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    DeleteClientWmTimers (pCD);
Packit b099d7
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Free up window context associations.  
Packit b099d7
     */
Packit b099d7
    DeleteClientContext (pCD);
Packit b099d7
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    /* 
Packit b099d7
     * Count backward for efficiency  --  
Packit b099d7
     *     removes from end of list.
Packit b099d7
     */
Packit b099d7
    for (i = pCD->numInhabited - 1; i >= 0; i--)
Packit b099d7
    {
Packit b099d7
	TakeClientOutOfWorkspace (
Packit b099d7
	    GetWorkspaceData(pCD->pSD, pCD->pWsList[i].wsID),
Packit b099d7
	    pCD);
Packit b099d7
    }
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Free up window manager resources:
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!(pCD->clientFlags & CLIENT_WM_CLIENTS))
Packit b099d7
    {
Packit b099d7
        if (pCD->clientName)
Packit b099d7
        {
Packit b099d7
	    XFree ((char *) (pCD->clientName));
Packit b099d7
        }
Packit b099d7
	if (pCD->clientClass)
Packit b099d7
	{
Packit b099d7
	    XFree ((char *) (pCD->clientClass));
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if ((pCD->clientFlags & CLIENT_HINTS_TITLE) && pCD->clientTitle)
Packit b099d7
    {
Packit b099d7
	XmStringFree (pCD->clientTitle);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if ((pCD->iconFlags & ICON_HINTS_TITLE) && pCD->iconTitle)
Packit b099d7
    {
Packit b099d7
	XmStringFree (pCD->iconTitle);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (pCD->clientCmapCount > 0)
Packit b099d7
    {
Packit b099d7
	for (i = 0; i < pCD->clientCmapCount; i++)
Packit b099d7
	{
Packit b099d7
	    if (pCD->cmapWindows[i] != pCD->client)
Packit b099d7
	    {
Packit b099d7
#ifndef	IBM_169380
Packit b099d7
		RemoveColormapWindowReference(pCD, pCD->cmapWindows[i]);
Packit b099d7
#else
Packit b099d7
		XDeleteContext (DISPLAY, pCD->cmapWindows[i],
Packit b099d7
		    wmGD.windowContextType);
Packit b099d7
#endif
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	XtFree ((char *) (pCD->cmapWindows));
Packit b099d7
	XtFree ((char *) (pCD->clientCmapList));
Packit b099d7
#ifndef OLD_COLORMAP /* colormap */
Packit b099d7
	XtFree ((char  *) (pCD->clientCmapFlags));
Packit b099d7
#endif
Packit b099d7
    }
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    /*
Packit b099d7
     * Insure list of initial properties has been freed.
Packit b099d7
     */
Packit b099d7
    DiscardInitialPropertyList (pCD);
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * free up list of workspace specific data
Packit b099d7
     */
Packit b099d7
    if ((pCD)->pWsList)
Packit b099d7
    {
Packit b099d7
	XtFree ((char *) (pCD->pWsList));
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * free up workspace hints
Packit b099d7
     */
Packit b099d7
    if (pCD->pWorkspaceHints)
Packit b099d7
    {
Packit b099d7
	XtFree ((char *)pCD->pWorkspaceHints);
Packit b099d7
    }
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
    if (pCD->smClientID)
Packit b099d7
	XFree (pCD->smClientID);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Clean up references to this data before we free it.
Packit b099d7
     */
Packit b099d7
    if (wmGD.menuClient == pCD) {
Packit b099d7
	wmGD.menuClient = NULL;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (wmGD.gadgetClient == pCD) {
Packit b099d7
	wmGD.gadgetClient = NULL;
Packit b099d7
	wmGD.gadgetDepressed = 0;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (wmGD.clickData.pCD == pCD) {
Packit b099d7
	wmGD.clickData.pCD = NULL;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (wmGD.nextKeyboardFocus == pCD)
Packit b099d7
	wmGD.nextKeyboardFocus = NULL;
Packit b099d7
    if (wmGD.keyboardFocus == pCD)
Packit b099d7
	wmGD.keyboardFocus = NULL;
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Fix for 5325 - Delete reference by dirty stack 
Packit b099d7
 */
Packit b099d7
    ClearDirtyStackEntry(pCD);
Packit b099d7
Packit b099d7
    XtFree ((char *)pCD);
Packit b099d7
Packit b099d7
Packit b099d7
} /* END OF FUNCTION WithdrawWindow */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  DeleteClientContext (pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function deletes the client from the X context manager
Packit b099d7
 *  
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD 	- pointer to client data 
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *
Packit b099d7
 *  Comments:
Packit b099d7
 *  --------
Packit b099d7
 * 
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void DeleteClientContext (ClientData *pCD)
Packit b099d7
{
Packit b099d7
    /*
Packit b099d7
     * Free up window context associations.  The context for the client
Packit b099d7
     * window is always set if there is a client data structure.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    XDeleteContext (DISPLAY, pCD->client, wmGD.windowContextType);
Packit b099d7
    if (pCD->clientFlags & CLIENT_CONTEXT_SAVED)
Packit b099d7
    {
Packit b099d7
	XDeleteContext (DISPLAY, pCD->clientFrameWin, wmGD.windowContextType);
Packit b099d7
	XDeleteContext (DISPLAY, pCD->clientBaseWin, wmGD.windowContextType);
Packit b099d7
	if (DECOUPLE_TITLE_APPEARANCE(pCD))
Packit b099d7
	{
Packit b099d7
	    XDeleteContext (DISPLAY, pCD->clientTitleWin,
Packit b099d7
		wmGD.windowContextType);
Packit b099d7
	}
Packit b099d7
	if (ICON_FRAME_WIN(pCD)) 
Packit b099d7
	{
Packit b099d7
#ifdef WSM
Packit b099d7
            int k;
Packit b099d7
Packit b099d7
	    for (k=0; k < pCD->numInhabited; k++)
Packit b099d7
	    {
Packit b099d7
		XDeleteContext (DISPLAY, pCD->pWsList[k].iconFrameWin, 
Packit b099d7
				 wmGD.windowContextType);
Packit b099d7
	    }
Packit b099d7
#else /* WSM */
Packit b099d7
	    XDeleteContext (DISPLAY, pCD->iconFrameWin, 
Packit b099d7
	                     wmGD.windowContextType);
Packit b099d7
#endif /* WSM */
Packit b099d7
	}
Packit b099d7
	pCD->clientFlags &= ~CLIENT_CONTEXT_SAVED;
Packit b099d7
    }
Packit b099d7
Packit b099d7
} /* END OF FUNCTION DeleteClientContext */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ResetWitdrawnFocii (pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function resets the various types of focus if they are set to a
Packit b099d7
 *  window being withdrawn.
Packit b099d7
 *  
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD 	- pointer to client data 
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *
Packit b099d7
 *  Comments:
Packit b099d7
 *  --------
Packit b099d7
 * 
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void ResetWithdrawnFocii (ClientData *pCD)
Packit b099d7
{
Packit b099d7
    if ((wmGD.keyboardFocus == pCD) ||
Packit b099d7
	/* BEGIN fix for CDExc21090 */
Packit b099d7
	((wmGD.keyboardFocus == (ClientData *)NULL) &&
Packit b099d7
	 (wmGD.nextKeyboardFocus == pCD) &&
Packit b099d7
	 (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT)))
Packit b099d7
	/* END fix for CDExc21090 */
Packit b099d7
    {
Packit b099d7
	if (wmGD.autoKeyFocus &&
Packit b099d7
	    (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
Packit b099d7
	{
Packit b099d7
	    /* local hack: if we've already received a map for a new
Packit b099d7
	    ** focus window, be sure to use wmGD.nextKeyboardFocus; otherwise 
Packit b099d7
	    ** AutoResetKeyFocus chooses an essentially arbitrary window to 
Packit b099d7
	    ** set focus to. 
Packit b099d7
	    */
Packit b099d7
	    if (wmGD.nextKeyboardFocus == pCD)
Packit b099d7
		    AutoResetKeyFocus (pCD, GetTimestamp());
Packit b099d7
	    else
Packit b099d7
	        Do_Focus_Key ((ClientData *)wmGD.nextKeyboardFocus, 
Packit b099d7
				GetTimestamp(), ALWAYS_SET_FOCUS);
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Set the focus to the default state if the focus is not in
Packit b099d7
	     * the process of being set (i.e. a FocusIn event will be 
Packit b099d7
	     * comming along shortly.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    if (wmGD.nextKeyboardFocus == wmGD.keyboardFocus)
Packit b099d7
	    {
Packit b099d7
	        Do_Focus_Key ((ClientData *)NULL, GetTimestamp(),
Packit b099d7
		    ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	SetKeyboardFocus ((ClientData *)NULL, 0);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (((pCD->inputMode == MWM_INPUT_PRIMARY_APPLICATION_MODAL) ||
Packit b099d7
         (pCD->inputMode == MWM_INPUT_FULL_APPLICATION_MODAL)) &&
Packit b099d7
	(wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * Repair the focus if an application modal dialog went 
Packit b099d7
	 * away. We may not see an enter event and have the focus
Packit b099d7
	 * set to the wrong place.
Packit b099d7
	 */
Packit b099d7
	RepairFocus ();
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (wmGD.nextKeyboardFocus == pCD)
Packit b099d7
    {
Packit b099d7
	wmGD.nextKeyboardFocus = NULL;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (ACTIVE_PSD->colormapFocus == pCD)
Packit b099d7
    {
Packit b099d7
	SetColormapFocus (ACTIVE_PSD, (ClientData *)NULL);
Packit b099d7
    }
Packit b099d7
Packit b099d7
} /* END OF FUNCTION ResetWithdrawnFocii */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  FreeClientFrame (pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function frees up frame windows and associated resources.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD		- pointer to client data
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void FreeClientFrame (ClientData *pCD)
Packit b099d7
{
Packit b099d7
    if (pCD->pclientTopShadows) {
Packit b099d7
	FreeRList (pCD->pclientTopShadows);
Packit b099d7
	pCD->pclientTopShadows = NULL;
Packit b099d7
    }
Packit b099d7
    if (pCD->pclientBottomShadows) {
Packit b099d7
	FreeRList (pCD->pclientBottomShadows);
Packit b099d7
	pCD->pclientBottomShadows = NULL;
Packit b099d7
    }
Packit b099d7
    if (pCD->pclientTitleTopShadows) {
Packit b099d7
	FreeRList (pCD->pclientTitleTopShadows);
Packit b099d7
	pCD->pclientTitleTopShadows = NULL;
Packit b099d7
    }
Packit b099d7
    if (pCD->pclientTitleBottomShadows) {
Packit b099d7
	FreeRList (pCD->pclientTitleBottomShadows);
Packit b099d7
	pCD->pclientTitleBottomShadows = NULL;
Packit b099d7
    }
Packit b099d7
    if (pCD->pclientMatteTopShadows) {
Packit b099d7
	FreeRList (pCD->pclientMatteTopShadows);
Packit b099d7
	pCD->pclientMatteTopShadows = NULL;
Packit b099d7
    }
Packit b099d7
    if (pCD->pclientMatteBottomShadows) {
Packit b099d7
	FreeRList (pCD->pclientMatteBottomShadows);
Packit b099d7
	pCD->pclientMatteBottomShadows = NULL;
Packit b099d7
    }
Packit b099d7
    if (pCD->pTitleGadgets) {
Packit b099d7
	XtFree ((char *)pCD->pTitleGadgets);
Packit b099d7
	pCD->pTitleGadgets = NULL;
Packit b099d7
	pCD->cTitleGadgets = 0;
Packit b099d7
    }
Packit b099d7
    if (pCD->pResizeGadgets) {
Packit b099d7
	XtFree ((char *)pCD->pResizeGadgets);
Packit b099d7
	pCD->pResizeGadgets = NULL;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* destroy frame window & all children */
Packit b099d7
    XDestroyWindow (DISPLAY, pCD->clientFrameWin);
Packit b099d7
Packit b099d7
} /* END OF FUNCTION FreeClientFrame */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  FreeIcon (pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function frees up icon windows and associated resources.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD		- pointer to client data
Packit b099d7
 * 
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void FreeIcon (ClientData *pCD)
Packit b099d7
{
Packit b099d7
#ifdef WSM
Packit b099d7
    WmWorkspaceData *pWsTmp;
Packit b099d7
    int i;
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
    if (pCD->piconTopShadows) {
Packit b099d7
	FreeRList (pCD->piconTopShadows);
Packit b099d7
	pCD->piconTopShadows = NULL;
Packit b099d7
    }
Packit b099d7
    if (pCD->piconBottomShadows) {
Packit b099d7
	FreeRList (pCD->piconBottomShadows);
Packit b099d7
	pCD->piconBottomShadows = NULL;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * destroy frame window & all children 
Packit b099d7
     */
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    if ((pCD->pSD->useIconBox) && pCD->pWsList[0].pIconBox)
Packit b099d7
    {
Packit b099d7
	/* 
Packit b099d7
	 * We're using icon boxes and it's in at least one ...
Packit b099d7
	 * Delete from all workspaces we live in
Packit b099d7
	 */
Packit b099d7
	for (i = 0; i< pCD->numInhabited; i++)
Packit b099d7
	{
Packit b099d7
	    if (pWsTmp = GetWorkspaceData(pCD->pSD, pCD->pWsList[i].wsID))
Packit b099d7
	    {
Packit b099d7
		DeleteIconFromBox (pWsTmp->pIconBox, pCD);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
	/* only one window, so destroying its first reference will
Packit b099d7
	 * clean it up adequately
Packit b099d7
	 */
Packit b099d7
	if (pCD->pWsList[0].iconFrameWin)
Packit b099d7
	{
Packit b099d7
	    XDestroyWindow (DISPLAY, pCD->pWsList[0].iconFrameWin);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
#else /* WSM */
Packit b099d7
    if (pCD->pSD->useIconBox && P_ICON_BOX(pCD))
Packit b099d7
    {
Packit b099d7
	DeleteIconFromBox (pCD->pSD->pActiveWS->pIconBox, pCD);
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
	XDestroyWindow (DISPLAY, pCD->iconFrameWin);
Packit b099d7
    }
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
} /* END OF FUNCTION FreeIcon */
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  WithdrawDialog (dialogboxW)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function removes a DialogBox widget "client" from the set of windows 
Packit b099d7
 *  that are managed by the window manager.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  dialogboxW = DialogBox widget to withdraw.
Packit b099d7
 * 
Packit b099d7
 *  Comments:
Packit b099d7
 *  --------
Packit b099d7
 *  Does not maintain the WM_STATE property on the dialog "client".
Packit b099d7
 * 
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void WithdrawDialog (Widget dialogboxW)
Packit b099d7
{
Packit b099d7
#ifdef WSM
Packit b099d7
    int i;
Packit b099d7
#endif /* WSM */
Packit b099d7
    ClientData *pCD = NULL;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Get the dialog shell window client data.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (XFindContext (DISPLAY, XtWindow (XtParent (dialogboxW)),
Packit b099d7
		      wmGD.windowContextType, (caddr_t *)&pCD))
Packit b099d7
      return;
Packit b099d7
Packit b099d7
    XtUnmanageChild (dialogboxW);
Packit b099d7
    DeleteClientFromList (ACTIVE_WS, pCD);
Packit b099d7
#ifdef WSM
Packit b099d7
    /* TakeClientOutOfWorkspace (ACTIVE_WS, pCD); */
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * Count backward for efficiency  --  
Packit b099d7
     *     removes from end of list.
Packit b099d7
     */
Packit b099d7
    for (i = pCD->numInhabited - 1; i >= 0; i--)
Packit b099d7
    {
Packit b099d7
	TakeClientOutOfWorkspace (
Packit b099d7
	    GetWorkspaceData(pCD->pSD, pCD->pWsList[i].wsID),
Packit b099d7
	    pCD);
Packit b099d7
    }
Packit b099d7
#endif /* WSM */
Packit b099d7
    ResetWithdrawnFocii (pCD);
Packit b099d7
    XUnmapWindow (DISPLAY, pCD->clientFrameWin);
Packit b099d7
Packit b099d7
} /* END OF FUNCTION WithdrawDialog */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ReManageDialog (pSD, dialogboxW)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function remanages a DialogBox "client" that was unmanaged via 
Packit b099d7
 *  WithdrawDialog ().
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pSD = pointer to screen data
Packit b099d7
 *  dialogboxW = DialogBox widget to remanage.
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  Does not maintain the WM_STATE property on the dialog "client".
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void ReManageDialog (WmScreenData *pSD, Widget dialogboxW)
Packit b099d7
{
Packit b099d7
    ClientData *pCD = NULL;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Get the dialog shell window client data.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (XFindContext (DISPLAY, XtWindow (XtParent (dialogboxW)),
Packit b099d7
		      wmGD.windowContextType, (caddr_t *)&pCD))
Packit b099d7
      return;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * The order is important here:
Packit b099d7
     */
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    /*
Packit b099d7
     * Put system modal windows in all workspaces to
Packit b099d7
     * avoid the race condition of the window coming up
Packit b099d7
     * just as the user switches workspaces OR when
Packit b099d7
     * the window is up and a user switces workspaces
Packit b099d7
     * with a key binding.  We may want to eventually short 
Packit b099d7
     * circuit F_Functions any time there is a modal
Packit b099d7
     * window up, but for now, we will just make sure
Packit b099d7
     * the modal window appears in all workspaces 
Packit b099d7
     */
Packit b099d7
Packit b099d7
    pCD->dtwmFunctions |= DtWM_FUNCTION_OCCUPY_WS;
Packit b099d7
    F_AddToAllWorkspaces(0, pCD, 0);
Packit b099d7
    pCD->dtwmFunctions &= ~DtWM_FUNCTION_OCCUPY_WS;
Packit b099d7
#endif /* WSM */
Packit b099d7
Packit b099d7
    if (pSD->clientList)
Packit b099d7
    {
Packit b099d7
      StackWindow (pSD->pActiveWS, &pCD->clientEntry,
Packit b099d7
                    TRUE, (ClientListEntry *) NULL);
Packit b099d7
    }
Packit b099d7
    AddClientToList (pSD->pActiveWS, pCD, True /*on top*/);
Packit b099d7
    XMapWindow (DISPLAY, pCD->clientFrameWin);
Packit b099d7
    XtManageChild (dialogboxW);
Packit b099d7
Packit b099d7
    if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
Packit b099d7
    {
Packit b099d7
	Do_Focus_Key (pCD, GetTimestamp() , ALWAYS_SET_FOCUS);
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
} /* END OF FUNCTION ReManageDialog */
Packit b099d7
Packit b099d7
#ifdef PANELIST
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  RegisterEmbeddedClients (wPanelist, pECD, count)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function registers a list of clients to be embedded in the
Packit b099d7
 *  front panel subsystem.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  wPanelist = front panel object (widget)
Packit b099d7
 *  pECD = pointer to list of data for clients to embed
Packit b099d7
 *  count = number of elements in the list
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void
Packit b099d7
RegisterEmbeddedClients (
Packit b099d7
	Widget wPanelist, 
Packit b099d7
	WmFpEmbeddedClientList pECD, 
Packit b099d7
	int count)
Packit b099d7
{
Packit b099d7
    WmScreenData *pSD;
Packit b099d7
    int i;
Packit b099d7
Packit b099d7
    for (i= 0; i < wmGD.numScreens; i++)
Packit b099d7
    {
Packit b099d7
	pSD = &(wmGD.Screens[i]);
Packit b099d7
Packit b099d7
	if (pSD->managed)
Packit b099d7
	{
Packit b099d7
	   if (pSD->wPanelist == wPanelist)
Packit b099d7
	       break;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (i < wmGD.numScreens)
Packit b099d7
    {
Packit b099d7
	pSD->pECD = (struct _WmFpEmbeddedClientData *) pECD;
Packit b099d7
	pSD->numEmbeddedClients = count;
Packit b099d7
    }
Packit b099d7
#ifdef DEBUG
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
	fprintf (stderr, "Couldn't match wPanelist to screen data\n");
Packit b099d7
    }
Packit b099d7
#endif /* DEBUG */
Packit b099d7
Packit b099d7
} /* END OF FUNCTION RegisterEmbeddedClients */
Packit b099d7
Packit b099d7

Packit b099d7
#define LTT_INCREMENT  16
Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ListTransientSubtree (pCD, ppWins, pSize, pCount)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function returns the list of windows in a transient window
Packit b099d7
 *  tree.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD		- pointer to client data of a window.
Packit b099d7
 *  ppWins	- address of a pointer to a list of windows 
Packit b099d7
 *		  (this must be in the heap -- XtMalloc).
Packit b099d7
 *  pSize	- address of variable with size of list
Packit b099d7
 *  pCount	- address of variable with number of windows in list
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  *ppWins	- may point to a new area of memory if list grows
Packit b099d7
 *  *pSize	- if list has to grow, this may be bigger
Packit b099d7
 *  *pCount	- number of windows in the list
Packit b099d7
 *
Packit b099d7
 *  Comments
Packit b099d7
 *  --------
Packit b099d7
 *  The list should be freed when done with XtFree().
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
static void
Packit b099d7
ListTransientSubtree (
Packit b099d7
	ClientData *pCD,
Packit b099d7
	Window **ppWins,
Packit b099d7
	int *pSize,
Packit b099d7
	int *pCount)
Packit b099d7
{
Packit b099d7
    /*
Packit b099d7
     * Check size
Packit b099d7
     */
Packit b099d7
    if (*pCount == *pSize) 
Packit b099d7
    {
Packit b099d7
	*pSize += LTT_INCREMENT;
Packit b099d7
	*ppWins = (Window *) 
Packit b099d7
		XtRealloc ((char *) *ppWins, (*pSize * sizeof(Window)));
Packit b099d7
    }
Packit b099d7
    /*
Packit b099d7
     * Add this window to the list
Packit b099d7
     */
Packit b099d7
    (*ppWins)[*pCount] = pCD->client;
Packit b099d7
    *pCount += 1;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Add siblings
Packit b099d7
     */
Packit b099d7
    if (pCD->transientSiblings)
Packit b099d7
	ListTransientSubtree (pCD->transientSiblings, ppWins, pSize, pCount);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Add children
Packit b099d7
     */
Packit b099d7
    if (pCD->transientChildren)
Packit b099d7
	ListTransientSubtree (pCD->transientChildren, ppWins, pSize, pCount);
Packit b099d7
Packit b099d7
    
Packit b099d7
} /* END OF FUNCTION ListTransientSubtree */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ListTransientTree (pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function returns the list of windows in a transient window
Packit b099d7
 *  tree.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD		- pointer to client data of a primary window.
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  none
Packit b099d7
 *
Packit b099d7
 *  Comments
Packit b099d7
 *  --------
Packit b099d7
 *  The list should be freed when done with XtFree().
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
static Window *
Packit b099d7
ListTransientTree (
Packit b099d7
	ClientData *pCD)
Packit b099d7
{
Packit b099d7
    Window *pWins;
Packit b099d7
    int count;
Packit b099d7
    int iSize;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Initial allocation
Packit b099d7
     */
Packit b099d7
    iSize = LTT_INCREMENT;
Packit b099d7
    pWins = (Window *) XtMalloc (iSize * sizeof(Window));
Packit b099d7
    count = 0;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Add this window to the list
Packit b099d7
     */
Packit b099d7
    ListTransientSubtree (pCD, &pWins, &iSize, &count);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Add terminator to end of window list
Packit b099d7
     */
Packit b099d7
    if (count == iSize) 
Packit b099d7
    {
Packit b099d7
	iSize += LTT_INCREMENT;
Packit b099d7
	pWins = (Window *) 
Packit b099d7
		XtRealloc ((char *)pWins, (iSize * sizeof(Window)));
Packit b099d7
    }
Packit b099d7
    pWins[count++] = None;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Return the list of windows found
Packit b099d7
     */
Packit b099d7
    return (pWins);
Packit b099d7
    
Packit b099d7
} /* END OF FUNCTION ListTransientTree */
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ReManageWindow (pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function unmanages and remanages a window and it's associated
Packit b099d7
 *  transients.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD		- pointer to client data of a primary window.
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  none
Packit b099d7
 *
Packit b099d7
 *  Comments
Packit b099d7
 *  --------
Packit b099d7
 *  The pointer pCD is invalid after calling this function -- a
Packit b099d7
 *  side-effect of unmanaging the client before remanaging it.
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
static void
Packit b099d7
ReManageWindow (
Packit b099d7
	ClientData *pCD)
Packit b099d7
{
Packit b099d7
    long manageFlags = MANAGEW_NORMAL;
Packit b099d7
    Window *pWins, *pW;
Packit b099d7
    WmScreenData *pSD;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Get the list of windows in the transient window tree.
Packit b099d7
     */
Packit b099d7
    pWins = ListTransientTree (pCD);
Packit b099d7
Packit b099d7
    pSD = pCD->pSD;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Unmanage this window and associated transients
Packit b099d7
     */
Packit b099d7
    UnManageWindow (pCD);
Packit b099d7
Packit b099d7
    /*** pCD is no longer a valid pointer!!! ***/
Packit b099d7
    
Packit b099d7
    /*
Packit b099d7
     * Remanage this window and its secondaries
Packit b099d7
     */
Packit b099d7
    pW = pWins;
Packit b099d7
    while (*pW != None)
Packit b099d7
    {
Packit b099d7
	ManageWindow (pSD, *pW, manageFlags);
Packit b099d7
	pW++;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XtFree ((char *) pWins);
Packit b099d7
Packit b099d7
} /* END OF FUNCTION ReManageWindow */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ScanForEmbeddedClients (pSD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function scans the managed windows and identifies those that
Packit b099d7
 *  should be embedded clients in the front panel
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pSD		- pointer to screen data.
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void
Packit b099d7
ScanForEmbeddedClients (
Packit b099d7
	WmScreenData *pSD)
Packit b099d7
{
Packit b099d7
    ClientData *pCD;
Packit b099d7
    ClientListEntry *pCLE;
Packit b099d7
    WmFpEmbeddedClientData *pECD;
Packit b099d7
    Boolean bReset;
Packit b099d7
    long manageFlags = 0L;
Packit b099d7
    Window *pWins, *pW;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Search through all the windows we're managing right now to
Packit b099d7
     *  see if any should be embedded in a front/sub panel.
Packit b099d7
     */
Packit b099d7
    pCLE = pSD->clientList;
Packit b099d7
    bReset = False;
Packit b099d7
Packit b099d7
    while (pCLE != NULL)
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * See if this is an previously unrecognized embedded client
Packit b099d7
	 */
Packit b099d7
	pCD = pCLE->pCD;
Packit b099d7
Packit b099d7
	if ((pCD->pECD == NULL ) && IsEmbeddedClient (pCD, &pECD))
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Remanage this window and associated transients
Packit b099d7
	     */
Packit b099d7
	    ReManageWindow (pCD);
Packit b099d7
	    /*
Packit b099d7
	     * At this point pCD is no longer valid and the
Packit b099d7
	     * pSD->clientList has been changed.
Packit b099d7
	     */
Packit b099d7
	    bReset = True;
Packit b099d7
	}
Packit b099d7
	
Packit b099d7
	/*
Packit b099d7
	 * Test for exit condition 
Packit b099d7
	 */
Packit b099d7
	if (pCLE == pSD->lastClient) 
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Gone all the way through the list without finding
Packit b099d7
	     * anything -- time to quit
Packit b099d7
	     */
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
	else if (bReset)
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Remanaging a client restructures the client list.
Packit b099d7
	     * Start over at the beginning.
Packit b099d7
	     */
Packit b099d7
	    bReset = False;
Packit b099d7
	    pCLE = pSD->clientList;
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Move to next client.
Packit b099d7
	     */
Packit b099d7
	    pCLE = pCLE->nextSibling;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
} /* END OF FUNCTION ScanForEmbeddedClients */
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  IsEmbeddedClient (pCD, ppECD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function tests a a client to see if it should be embedded
Packit b099d7
 *  in the front panel.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD = ptr to Client Data
Packit b099d7
 *  ppECD = ptr to returned embedded client data ptr
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  *ppECD = ptr to embedded client data
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
Boolean
Packit b099d7
Packit b099d7
IsEmbeddedClient (ClientData *pCD, WmFpEmbeddedClientData **ppECD)
Packit b099d7
Packit b099d7
{
Packit b099d7
    WmScreenData *pSD;
Packit b099d7
    int i;
Packit b099d7
    Boolean bFoundMatch = False;
Packit b099d7
    WmFpEmbeddedClientData *pECD;
Packit b099d7
Packit b099d7
    pSD = pCD->pSD;
Packit b099d7
    pECD = (WmFpEmbeddedClientData *) pSD->pECD;
Packit b099d7
Packit b099d7
    for (i = 0; i < pSD->numEmbeddedClients && !bFoundMatch; i++, pECD++)
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * It's an embedded client if 
Packit b099d7
	 *     the resource name matches a slot and 
Packit b099d7
	 *     it's not a subpanel and
Packit b099d7
	 *     the slot isn't already filled.
Packit b099d7
	 */
Packit b099d7
	if ((!strcmp ((char *)pCD->clientName, 
Packit b099d7
		      (char *)(pECD->pchResName))) &&
Packit b099d7
	    (!(pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL)) &&
Packit b099d7
	    (!pECD->pCD))
Packit b099d7
	{
Packit b099d7
	    *ppECD = pECD;
Packit b099d7
	    bFoundMatch = True;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    return (bFoundMatch);
Packit b099d7
Packit b099d7
} /* END OF FUNCTION IsEmbeddedClient */
Packit b099d7
Packit b099d7

Packit b099d7
/******************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ManageEmbeddedClient (pCD, pECD, manageFlags)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This is the function that is used to setup a client window
Packit b099d7
 *  in the front panel.
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD = initialized client data, including window of client that
Packit b099d7
 *        we want to manage.
Packit b099d7
 *  pECD = ptr to embedded client entry for this client
Packit b099d7
 *
Packit b099d7
 *  manageFlags	= additional control information 
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  Returns False if normal client processing needs to be done.
Packit b099d7
 *
Packit b099d7
 *  Returns True if this client has been embedded directly in the
Packit b099d7
 *  front panel and is NOT to be managed as a normal top level
Packit b099d7
 *  window--no further processing required.
Packit b099d7
 ******************************<->***********************************/
Packit b099d7
Boolean
Packit b099d7
Packit b099d7
ManageEmbeddedClient (
Packit b099d7
    ClientData *pCD, 
Packit b099d7
    WmFpEmbeddedClientData *pECD,
Packit b099d7
    long manageFlags)
Packit b099d7
Packit b099d7
{
Packit b099d7
    int wsIndex;
Packit b099d7
    int i;
Packit b099d7
    XWindowChanges windowChanges;
Packit b099d7
    unsigned int mask;
Packit b099d7
    WmFpPushRecallClientData *pPRCD;
Packit b099d7
Packit b099d7
    if (!pECD || !pCD)
Packit b099d7
    {
Packit b099d7
	return (False);
Packit b099d7
    }
Packit b099d7
   
Packit b099d7
    /*
Packit b099d7
     * Add to all workspaces
Packit b099d7
     */
Packit b099d7
    pCD->dtwmFunctions |= DtWM_FUNCTION_OCCUPY_WS;
Packit b099d7
Packit b099d7
    F_AddToAllWorkspaces(0, pCD, 0);
Packit b099d7
Packit b099d7
    pCD->dtwmFunctions &= ~DtWM_FUNCTION_OCCUPY_WS;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Set client list entries 
Packit b099d7
     * (in a list by itself)
Packit b099d7
     */
Packit b099d7
    pCD->clientEntry.type = NORMAL_STATE;
Packit b099d7
    pCD->clientEntry.pCD = pCD;
Packit b099d7
    pCD->clientEntry.nextSibling = NULL;
Packit b099d7
    pCD->clientEntry.prevSibling = NULL;
Packit b099d7
Packit b099d7
    pCD->iconEntry.type = MINIMIZED_STATE;
Packit b099d7
    pCD->iconEntry.pCD = pCD;
Packit b099d7
    pCD->iconEntry.nextSibling = NULL;
Packit b099d7
    pCD->iconEntry.prevSibling = NULL;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Save context for event processing.
Packit b099d7
     *
Packit b099d7
     */
Packit b099d7
Packit b099d7
    XSaveContext (DISPLAY, pCD->client, wmGD.windowContextType, 
Packit b099d7
		    (caddr_t)pCD);
Packit b099d7
Packit b099d7
    if (!(pCD->clientFlags & CLIENT_WM_CLIENTS))
Packit b099d7
    {
Packit b099d7
	XChangeSaveSet (DISPLAY, pCD->client, SetModeInsert);
Packit b099d7
	XChangeSaveSet (DISPLAY1, pCD->client, SetModeInsert);
Packit b099d7
	pCD->clientFlags |= CLIENT_IN_SAVE_SET;
Packit b099d7
    }
Packit b099d7
    if (!(manageFlags & MANAGEW_WM_CLIENTS))
Packit b099d7
    {
Packit b099d7
	XSync (DISPLAY1, False);
Packit b099d7
Packit b099d7
	if (pCD->clientFlags & CLIENT_DESTROYED)
Packit b099d7
	{
Packit b099d7
	    UnManageWindow (pCD);
Packit b099d7
	    return (True); 
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XtAddEventHandler(XtWindowToWidget (DISPLAY1, pECD->winParent),
Packit b099d7
		(SubstructureRedirectMask | SubstructureNotifyMask),
Packit b099d7
	        False,
Packit b099d7
		(XtEventHandler)HandleSubstructEvents,
Packit b099d7
		(XtPointer)(pCD));
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * Fill in more client data
Packit b099d7
     */
Packit b099d7
    pCD->clientX = pECD->x;
Packit b099d7
    pCD->clientY = pECD->y;
Packit b099d7
    pCD->clientWidth = pECD->width;
Packit b099d7
    pCD->clientHeight = pECD->height;
Packit b099d7
Packit b099d7
    pCD->clientFrameWin = 0;
Packit b099d7
    pCD->clientBaseWin = pECD->winParent;
Packit b099d7
Packit b099d7
    pECD->pCD = pCD;
Packit b099d7
    pCD->pECD = (void *) pECD;
Packit b099d7
Packit b099d7
#ifdef WSM
Packit b099d7
    SetClientWsIndex(pCD);
Packit b099d7
#endif
Packit b099d7
    SetClientWMState (pCD, NormalState, NORMAL_STATE);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Set state on subpanel in case it never gets mapped
Packit b099d7
     * to prevent session manager from finding an embedded
Packit b099d7
     * client on its own.
Packit b099d7
     */
Packit b099d7
    ForceSubpanelWMState (pECD->winParent);
Packit b099d7
Packit b099d7
    XReparentWindow (DISPLAY1, pCD->client, 
Packit b099d7
		     pECD->winParent,
Packit b099d7
		     pECD->x, pECD->y);
Packit b099d7
    pCD->clientFlags |= CLIENT_REPARENTED;
Packit b099d7
Packit b099d7
    windowChanges.width = pECD->width;
Packit b099d7
    windowChanges.height = pECD->height;
Packit b099d7
    windowChanges.border_width = 0;
Packit b099d7
    mask = (CWWidth | CWHeight | CWBorderWidth);
Packit b099d7
Packit b099d7
    XConfigureWindow (DISPLAY1, pCD->client, mask, &windowChanges);
Packit b099d7
Packit b099d7
    XMapWindow (DISPLAY1, pCD->client);
Packit b099d7
    if (pCD->iconWindow)
Packit b099d7
    {
Packit b099d7
	XUnmapWindow (DISPLAY, pCD->iconWindow);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    UpdateEmbeddedClientsProperty (pCD->pSD);
Packit b099d7
Packit b099d7
    SendConfigureNotify (pCD);
Packit b099d7
Packit b099d7
    if (IsPushRecallClient (pCD, &pPRCD))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * There should only be one instance of this
Packit b099d7
	 * client started from a front panel button.
Packit b099d7
	 */
Packit b099d7
	pPRCD->pCD = pCD;
Packit b099d7
	pCD->pPRCD = (void *) pPRCD;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    WmStopWaiting(); 
Packit b099d7
Packit b099d7
    return(True); /* successful embedation */
Packit b099d7
Packit b099d7
} /* END OF FUNCTION ManageEmbeddedClient */
Packit b099d7
Packit b099d7

Packit b099d7
/******************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ReparentEmbeddedClient (pECD, newControl, newWin, x, y, width, height)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pECD = ptr to embedded client entry for this client
Packit b099d7
 *  newControl = widget for new "parent" widget
Packit b099d7
 *  newWin = window ID of window that this embedded client will be
Packit b099d7
 *           a parent of. This is needed in case the control is a
Packit b099d7
 *           gadget.
Packit b099d7
 *  x = x-coord position within newWin where UL corner of the embedded
Packit b099d7
 *      client will go.
Packit b099d7
 *  y = y-coord as described above.
Packit b099d7
 *  width = desired width of embedded client in this new location
Packit b099d7
 *  height = desired height as above.
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  Returns False if embedded client was is not moved to the new
Packit b099d7
 *  location.
Packit b099d7
 *
Packit b099d7
 *  Returns True if this client has been reparented to the new
Packit b099d7
 *  control.
Packit b099d7
 ******************************<->***********************************/
Packit b099d7
Boolean
Packit b099d7
Packit b099d7
ReparentEmbeddedClient (
Packit b099d7
    WmFpEmbeddedClientData *pECD,
Packit b099d7
    Widget newControl,
Packit b099d7
    Window newWin,
Packit b099d7
    int x, 
Packit b099d7
    int y,
Packit b099d7
    unsigned int width, 
Packit b099d7
    unsigned int height
Packit b099d7
    )
Packit b099d7
Packit b099d7
{
Packit b099d7
    int wsIndex;
Packit b099d7
    int i;
Packit b099d7
    XWindowChanges windowChanges;
Packit b099d7
    unsigned int mask;
Packit b099d7
    WmFpPushRecallClientData *pPRCD;
Packit b099d7
    ClientData *pCD;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * If we have bogus data or if we're asked
Packit b099d7
     * to reparent to our current parent, then just
Packit b099d7
     * say no.
Packit b099d7
     */
Packit b099d7
    if ((pECD == NULL) || 
Packit b099d7
	(pECD->pCD == NULL) ||
Packit b099d7
	(pECD->winParent == newWin))
Packit b099d7
    {
Packit b099d7
	return (False);
Packit b099d7
    }
Packit b099d7
    pCD=pECD->pCD;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Need event handler on new parent window?
Packit b099d7
     */
Packit b099d7
    if (newWin != pECD->winParent)
Packit b099d7
    {
Packit b099d7
	XtRemoveEventHandler(XtWindowToWidget (DISPLAY1, pECD->winParent),
Packit b099d7
		(SubstructureRedirectMask | SubstructureNotifyMask),
Packit b099d7
	        False,
Packit b099d7
		(XtEventHandler)HandleSubstructEvents,
Packit b099d7
		(XtPointer)(pCD));
Packit b099d7
Packit b099d7
	XtAddEventHandler(XtWindowToWidget (DISPLAY1, newWin),
Packit b099d7
		(SubstructureRedirectMask | SubstructureNotifyMask),
Packit b099d7
	        False,
Packit b099d7
		(XtEventHandler)HandleSubstructEvents,
Packit b099d7
		(XtPointer)(pCD));
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * Update embedding and client data
Packit b099d7
     */
Packit b099d7
    pECD->wControl = newControl;
Packit b099d7
    pECD->winParent = newWin;
Packit b099d7
    pCD->clientX = pECD->x = x;
Packit b099d7
    pCD->clientY = pECD->y = y;
Packit b099d7
    pCD->clientWidth = pECD->width = width;
Packit b099d7
    pCD->clientHeight = pECD->height = height;
Packit b099d7
    pCD->clientBaseWin = pECD->winParent;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Set state on subpanel in case it never gets mapped
Packit b099d7
     * to prevent session manager from finding an embedded
Packit b099d7
     * client on its own.
Packit b099d7
     */
Packit b099d7
    ForceSubpanelWMState (pECD->winParent);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Do the actual reparent
Packit b099d7
     */
Packit b099d7
    XReparentWindow (DISPLAY1, pCD->client, 
Packit b099d7
		     pECD->winParent,
Packit b099d7
		     pECD->x, pECD->y);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Configure the embedded client
Packit b099d7
     */
Packit b099d7
    windowChanges.width = pECD->width;
Packit b099d7
    windowChanges.height = pECD->height;
Packit b099d7
    windowChanges.border_width = 0;
Packit b099d7
    mask = (CWWidth | CWHeight | CWBorderWidth);
Packit b099d7
Packit b099d7
    XConfigureWindow (DISPLAY1, pCD->client, mask, &windowChanges);
Packit b099d7
Packit b099d7
    XMapWindow (DISPLAY1, pCD->client);
Packit b099d7
Packit b099d7
    UpdateEmbeddedClientsProperty (pCD->pSD);
Packit b099d7
Packit b099d7
    SendConfigureNotify (pCD);
Packit b099d7
Packit b099d7
    return(True); /* successful reparent */
Packit b099d7
Packit b099d7
} /* END OF FUNCTION ReparentEmbeddedClient */
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ForceSubpanelWMState (win)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function forces a WM_STATE property on a subpanel window
Packit b099d7
 *  so that the session manager doesn't save multiple copies
Packit b099d7
 *  of embedded clients for subpanels that never get mapped.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  win = window ID of a subpanel window (not necessarily the top level!)
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
static void
Packit b099d7
ForceSubpanelWMState (Window win)
Packit b099d7
{
Packit b099d7
    ClientData *pCD = NULL;
Packit b099d7
    Window root, parent;
Packit b099d7
    Window *children = NULL;
Packit b099d7
    unsigned int numChildren;
Packit b099d7
    PropWMState *wmStateProp;
Packit b099d7
    Boolean bDone = False;
Packit b099d7
Packit b099d7
    while (!bDone)
Packit b099d7
    {
Packit b099d7
	if (!XQueryTree (DISPLAY, win, &root, &parent, 
Packit b099d7
		&children, &numChildren))
Packit b099d7
	{
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (!XFindContext(DISPLAY, win, wmGD.windowContextType, 
Packit b099d7
	    (caddr_t *)&pCD))
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Only continue if we're not already managing this subpanel.
Packit b099d7
	     */
Packit b099d7
	    bDone = True;
Packit b099d7
	}
Packit b099d7
	else if (parent == root)
Packit b099d7
	{
Packit b099d7
	    if (wmStateProp = GetWMState (win))
Packit b099d7
	    {
Packit b099d7
		/*
Packit b099d7
		 * Already has a WM_STATE.
Packit b099d7
		 */
Packit b099d7
		XFree ((char *)wmStateProp);
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    {
Packit b099d7
		/*
Packit b099d7
		 * Add a dummy WM_STATE to foil the session manager
Packit b099d7
		 * search.
Packit b099d7
		 */
Packit b099d7
		SetWMState (win, WITHDRAWN_STATE, 0);
Packit b099d7
	    }
Packit b099d7
	    bDone = True;
Packit b099d7
	}
Packit b099d7
	else 
Packit b099d7
	{
Packit b099d7
	    /* continue ascent up to root */
Packit b099d7
	    win = parent;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	XFree ((char *) children);
Packit b099d7
    }
Packit b099d7
Packit b099d7
} /* END OF FUNCTION ForceSubpanelWMState */
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  RegisterPushRecallClients (wPanelist, pPRCD, count)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function registers a list of push_recallclients for the 
Packit b099d7
 *  front panel subsystem. 
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  wPanelist = front panel object (widget)
Packit b099d7
 *  pPRCD = pointer to list of data for clients
Packit b099d7
 *  count = number of elements in the list
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void
Packit b099d7
RegisterPushRecallClients (
Packit b099d7
	Widget wPanelist, 
Packit b099d7
	WmFpPushRecallClientList pPRCD, 
Packit b099d7
	int count)
Packit b099d7
{
Packit b099d7
    WmScreenData *pSD;
Packit b099d7
    int i;
Packit b099d7
Packit b099d7
    for (i= 0; i < wmGD.numScreens; i++)
Packit b099d7
    {
Packit b099d7
	pSD = &(wmGD.Screens[i]);
Packit b099d7
Packit b099d7
	if (pSD->managed)
Packit b099d7
	{
Packit b099d7
	   if (pSD->wPanelist == wPanelist)
Packit b099d7
	       break;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (i < wmGD.numScreens)
Packit b099d7
    {
Packit b099d7
	pSD->pPRCD = (struct _WmFpPushRecallClientData *) pPRCD;
Packit b099d7
	pSD->numPushRecallClients = count;
Packit b099d7
    }
Packit b099d7
#ifdef DEBUG
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
	fprintf (stderr, "Couldn't match wPanelist to screen data\n");
Packit b099d7
    }
Packit b099d7
#endif /* DEBUG */
Packit b099d7
Packit b099d7
    for (i = 0; i < pSD->numPushRecallClients ; i++, pPRCD++)
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * Initialize data in each slot
Packit b099d7
	 */
Packit b099d7
	pPRCD->tvTimeout.tv_sec = 0;
Packit b099d7
    }
Packit b099d7
Packit b099d7
} /* END OF FUNCTION RegisterPushRecallClients */
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  IsPushRecallClient (pCD, ppPRCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function tests a a client to see if it should be embedded
Packit b099d7
 *  in the front panel.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD = ptr to Client Data
Packit b099d7
 *  ppPRCD = ptr to returned embedded client data ptr
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  *ppPRCD = ptr to embedded client data
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
Boolean
Packit b099d7
Packit b099d7
IsPushRecallClient (ClientData *pCD, WmFpPushRecallClientData **ppPRCD)
Packit b099d7
Packit b099d7
{
Packit b099d7
    WmScreenData *pSD;
Packit b099d7
    int i;
Packit b099d7
    Boolean bFoundMatch = False;
Packit b099d7
    WmFpPushRecallClientData *pPRCD;
Packit b099d7
Packit b099d7
    pSD = pCD->pSD;
Packit b099d7
    pPRCD = (WmFpPushRecallClientData *) pSD->pPRCD;
Packit b099d7
Packit b099d7
    for (i = 0; i < pSD->numPushRecallClients && !bFoundMatch; i++, pPRCD++)
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * It's a push_recall client if the resource name matches
Packit b099d7
	 * a slot and the slot isn't already filled.
Packit b099d7
	 */
Packit b099d7
	if ((!strcmp ((char *)pCD->clientName, 
Packit b099d7
		     (char *)(pPRCD->pchResName))) &&
Packit b099d7
	    (!pPRCD->pCD))
Packit b099d7
	{
Packit b099d7
	    *ppPRCD = pPRCD;
Packit b099d7
	    bFoundMatch = True;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    return (bFoundMatch);
Packit b099d7
Packit b099d7
} /* END OF FUNCTION IsPushRecallClient */
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  ScanForPushRecallClients (pSD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function scans the managed windows and identifies those that
Packit b099d7
 *  should be push recall clients of the front panel
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pSD		- pointer to screen data.
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void
Packit b099d7
ScanForPushRecallClients (
Packit b099d7
	WmScreenData *pSD)
Packit b099d7
{
Packit b099d7
    ClientData *pCD;
Packit b099d7
    ClientListEntry *pCLE;
Packit b099d7
    WmFpPushRecallClientData *pPRCD;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     *  Search through all the windows we're managing right now 
Packit b099d7
     */
Packit b099d7
    pCLE = pSD->clientList;
Packit b099d7
Packit b099d7
    while (pCLE != NULL)
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * See if this is an previously unrecognized push recall client
Packit b099d7
	 */
Packit b099d7
	pCD = pCLE->pCD;
Packit b099d7
Packit b099d7
	if ((pCD->pPRCD == NULL ) && IsPushRecallClient (pCD, &pPRCD))
Packit b099d7
	{
Packit b099d7
	    CheckPushRecallClient (pCD);
Packit b099d7
	}
Packit b099d7
	
Packit b099d7
	/*
Packit b099d7
	 * Test for exit condition 
Packit b099d7
	 */
Packit b099d7
	if (pCLE == pSD->lastClient) 
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Gone all the way through the list without finding
Packit b099d7
	     * anything -- time to quit
Packit b099d7
	     */
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    /*
Packit b099d7
	     * Move to next client.
Packit b099d7
	     */
Packit b099d7
	    pCLE = pCLE->nextSibling;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
} /* END OF FUNCTION ScanForPushRecallClients */
Packit b099d7
Packit b099d7

Packit b099d7
/******************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  static void CheckPushRecallClient (pCD)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  Checks a client against the list of push recall clients to see
Packit b099d7
 *  if there are any matches. All matches are marked.
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pCD - pointer to the Client Data structure
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *
Packit b099d7
 *  Comments:
Packit b099d7
 *  --------
Packit b099d7
 *
Packit b099d7
 ******************************<->***********************************/
Packit b099d7
static void 
Packit b099d7
CheckPushRecallClient(
Packit b099d7
        ClientData *pCD)
Packit b099d7
{
Packit b099d7
    WmFpPushRecallClientData *pPRCD;
Packit b099d7
Packit b099d7
    while (IsPushRecallClient (pCD, &pPRCD))
Packit b099d7
    {
Packit b099d7
	/*
Packit b099d7
	 * There should only be one instance of this
Packit b099d7
	 * client started from a front panel button.
Packit b099d7
	 */
Packit b099d7
	pPRCD->pCD = pCD;
Packit b099d7
	pPRCD->tvTimeout.tv_sec = 0;
Packit b099d7
	if (!pCD->pPRCD)
Packit b099d7
	    pCD->pPRCD = (void *) pPRCD;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/******************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  static void HandleSubstructEvents (Widget w, caddr_t pCD, XEvent *event)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  Causes death of embedded clients to run through UnManageWindow()
Packit b099d7
 *  for proper cleanup.
Packit b099d7
 *
Packit b099d7
 *  Note there is one of these event handlers instantiated for
Packit b099d7
 *  each live client window in the front panel.  Hence, for each
Packit b099d7
 *  live client window death, each of the event handlers gets called
Packit b099d7
 *  once.  We need to ensure that we've got the right pCD before
Packit b099d7
 *  calling UnManageWindow() on it.
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  w   - not used
Packit b099d7
 *  pCD - pointer to the Client Data structure
Packit b099d7
 *  event - we only care about UnMapNotify
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *
Packit b099d7
 *  Comments:
Packit b099d7
 *  --------
Packit b099d7
 *  This routine is called LOTS of times, for all types of events.
Packit b099d7
 *
Packit b099d7
 ******************************<->***********************************/
Packit b099d7
static void 
Packit b099d7
HandleSubstructEvents(
Packit b099d7
        Widget w,
Packit b099d7
        caddr_t ptr,
Packit b099d7
        XEvent *event )
Packit b099d7
{
Packit b099d7
	struct _ClientData *pCD = (struct _ClientData *)ptr;
Packit b099d7
Packit b099d7
        switch (event->type)
Packit b099d7
	{
Packit b099d7
	    case UnmapNotify:
Packit b099d7
	    {
Packit b099d7
		if (pCD->client == event->xunmap.window)
Packit b099d7
		{
Packit b099d7
		    UnManageWindow (pCD);
Packit b099d7
		}
Packit b099d7
		break;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
} /* END OF FUNCTION HandleSubstructEvents */
Packit b099d7
Packit b099d7

Packit b099d7
/*******************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  UpdateEmbeddedClientsProperty (pSD)
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pSD - pointer to the screen data
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  True if successful, False otherwise.
Packit b099d7
 *
Packit b099d7
 *  Comments:
Packit b099d7
 *  --------
Packit b099d7
 *  The _DT_WORKSPACE_EMBEDDED_CLIENTS property on the 
Packit b099d7
 *  root window for the screen will be updated to reflect the
Packit b099d7
 *  current contents of the front panel
Packit b099d7
 *
Packit b099d7
 * 
Packit b099d7
 ******************************<->***********************************/
Packit b099d7
Boolean 
Packit b099d7
UpdateEmbeddedClientsProperty(
Packit b099d7
        WmScreenData *pSD )
Packit b099d7
{
Packit b099d7
    unsigned int numClients = 0;
Packit b099d7
    Window *pClients = NULL;
Packit b099d7
    Boolean rval = True;
Packit b099d7
    int i;
Packit b099d7
    WmFpEmbeddedClientData *pECD;
Packit b099d7
Packit b099d7
    pECD = (WmFpEmbeddedClientData *) pSD->pECD;
Packit b099d7
Packit b099d7
    for (i = 0; i < pSD->numEmbeddedClients; i++, pECD++)
Packit b099d7
    {
Packit b099d7
	if (pECD->pCD)
Packit b099d7
	{
Packit b099d7
	    numClients += 1;
Packit b099d7
Packit b099d7
	    if (!pClients) 
Packit b099d7
	    {
Packit b099d7
		pClients = (Window *) XtMalloc (sizeof(Window));
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    {
Packit b099d7
		pClients = (Window *) XtRealloc ((char *)pClients,
Packit b099d7
		    (numClients * (sizeof(Window))));
Packit b099d7
	    }
Packit b099d7
Packit b099d7
	    if (!pClients)
Packit b099d7
	    {
Packit b099d7
		Warning (
Packit b099d7
((char *)GETMESSAGE(4, 17, "Insufficient memory to write _DT_WORKSPACE_EMBEDDED_CLIENTS."))
Packit b099d7
			);
Packit b099d7
		rval = False;
Packit b099d7
		break;
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    {
Packit b099d7
		pClients[numClients-1] = pECD->pCD->client;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    SetEmbeddedClientsProperty (pSD->rootWindow, pClients,
Packit b099d7
	numClients);
Packit b099d7
Packit b099d7
    if (pClients != NULL)
Packit b099d7
    {
Packit b099d7
	XtFree ((char *)pClients);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return (rval);
Packit b099d7
} /* END OF FUNCTION UpdateEmbeddedClientsProperty */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*******************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  UnParentControls (pSD, unmap)
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  pSD - pointer to the screen data
Packit b099d7
 *  unmap - if True, then unmap the windows after reparenting to root
Packit b099d7
 * 
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *  none
Packit b099d7
 *
Packit b099d7
 *  Comments:
Packit b099d7
 *  --------
Packit b099d7
 *  Reparents clients embedded in the front panel back to the 
Packit b099d7
 *  root window
Packit b099d7
 * 
Packit b099d7
 ******************************<->***********************************/
Packit b099d7
void 
Packit b099d7
UnParentControls(
Packit b099d7
        WmScreenData *pSD,
Packit b099d7
        Boolean unmap )
Packit b099d7
{
Packit b099d7
    int i;
Packit b099d7
    ClientData *pCD;
Packit b099d7
    WmFpEmbeddedClientData *pECD;
Packit b099d7
    
Packit b099d7
    if (pSD && pSD->managed)
Packit b099d7
    {
Packit b099d7
	pECD = (WmFpEmbeddedClientData *) pSD->pECD;
Packit b099d7
	for (i = 0; i < pSD->numEmbeddedClients; i++, pECD++)
Packit b099d7
	{
Packit b099d7
	    pCD = pECD->pCD;
Packit b099d7
Packit b099d7
	    if (pCD)
Packit b099d7
	    {
Packit b099d7
		if ((pCD->clientFlags & CLIENT_IN_SAVE_SET) &&
Packit b099d7
		    !(pCD->clientFlags & CLIENT_DESTROYED))
Packit b099d7
		{
Packit b099d7
		    XRemoveFromSaveSet (DISPLAY, pCD->client);
Packit b099d7
		    XRemoveFromSaveSet (DISPLAY1, pCD->client);
Packit b099d7
		}
Packit b099d7
		
Packit b099d7
		XReparentWindow (DISPLAY,
Packit b099d7
				 pCD->client,
Packit b099d7
				 pSD->rootWindow,
Packit b099d7
				 pCD->clientX,
Packit b099d7
				 pCD->clientY);
Packit b099d7
		if (unmap)
Packit b099d7
		{
Packit b099d7
		    XUnmapWindow (DISPLAY, pCD->client);
Packit b099d7
		    if (pCD->iconWindow)
Packit b099d7
		    {
Packit b099d7
			if (pCD->clientFlags & ICON_IN_SAVE_SET)
Packit b099d7
			{
Packit b099d7
			    XRemoveFromSaveSet (DISPLAY, pCD->iconWindow);
Packit b099d7
			    pCD->clientFlags &= ~ICON_IN_SAVE_SET;
Packit b099d7
			}
Packit b099d7
			XUnmapWindow (DISPLAY, pCD->iconWindow);
Packit b099d7
		    }
Packit b099d7
		}
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
} /* END OF FUNCTION UnParentControl */
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************<->*************************************
Packit b099d7
 *
Packit b099d7
 *  RegisterIconBoxControl (wPanelist)
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Description:
Packit b099d7
 *  -----------
Packit b099d7
 *  This function registers the icon box control in a front panel
Packit b099d7
 *
Packit b099d7
 *
Packit b099d7
 *  Inputs:
Packit b099d7
 *  ------
Packit b099d7
 *  wPanelist = front panel object (widget)
Packit b099d7
 *
Packit b099d7
 *  Outputs:
Packit b099d7
 *  -------
Packit b099d7
 *
Packit b099d7
 *************************************<->***********************************/
Packit b099d7
Packit b099d7
void
Packit b099d7
RegisterIconBoxControl (Widget wPanelist)
Packit b099d7
{
Packit b099d7
    WmScreenData *pSD;
Packit b099d7
    int i;
Packit b099d7
Packit b099d7
    for (i= 0; i < wmGD.numScreens; i++)
Packit b099d7
    {
Packit b099d7
	pSD = &(wmGD.Screens[i]);
Packit b099d7
Packit b099d7
	if (pSD->managed)
Packit b099d7
	{
Packit b099d7
	   if (pSD->wPanelist == wPanelist)
Packit b099d7
	       break;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (i < wmGD.numScreens)
Packit b099d7
    {
Packit b099d7
	pSD->iconBoxControl = True;
Packit b099d7
	pSD->useIconBox = True;
Packit b099d7
    }
Packit b099d7
#ifdef DEBUG
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
	fprintf (stderr, "Couldn't match wPanelist to screen data\n");
Packit b099d7
    }
Packit b099d7
#endif /* DEBUG */
Packit b099d7
Packit b099d7
} /* END OF FUNCTION RegisterIconBoxControl */
Packit b099d7
Packit b099d7
#endif /* PANELIST */