2003 lines
44 KiB
C
2003 lines
44 KiB
C
/*
|
||
* CDE - Common Desktop Environment
|
||
*
|
||
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
||
*
|
||
* These libraries and programs are free software; you can
|
||
* redistribute them and/or modify them under the terms of the GNU
|
||
* Lesser General Public License as published by the Free Software
|
||
* Foundation; either version 2 of the License, or (at your option)
|
||
* any later version.
|
||
*
|
||
* These libraries and programs are distributed in the hope that
|
||
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
||
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
* PURPOSE. See the GNU Lesser General Public License for more
|
||
* details.
|
||
*
|
||
* You should have received a copy of the GNU Lesser General Public
|
||
* License along with these libraries and programs; if not, write
|
||
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
||
* Floor, Boston, MA 02110-1301 USA
|
||
*/
|
||
/*
|
||
* (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC.
|
||
* ALL RIGHTS RESERVED
|
||
*/
|
||
/*
|
||
* Motif Release 1.2.3
|
||
*/
|
||
/*
|
||
* (c) Copyright 1987, 1988, 1989, 1990, 1993 HEWLETT-PACKARD COMPANY */
|
||
|
||
/*
|
||
* Included Files:
|
||
*/
|
||
|
||
#include "WmGlobal.h"
|
||
#include "WmICCC.h"
|
||
#include <limits.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <Dt/WsmP.h>
|
||
#include <X11/Xatom.h>
|
||
#include <Xm/AtomMgr.h>
|
||
|
||
/*
|
||
* include extern functions
|
||
*/
|
||
|
||
#include "WmColormap.h"
|
||
#include "WmError.h"
|
||
#include "WmResParse.h"
|
||
#include "WmIconBox.h"
|
||
|
||
|
||
|
||
/*
|
||
* Function Declarations:
|
||
*/
|
||
|
||
#include "WmProperty.h"
|
||
|
||
|
||
/*
|
||
* Global Variables:
|
||
*/
|
||
|
||
static SizeHints sizeHints;
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* SizeHints *
|
||
* GetNormalHints (pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function replaces the XGetNormalHints Xlib function. This function
|
||
* gets the information in the WM_NORMAL_HINTS property on the client window.
|
||
* The property encoding can be any of the supported versions (R2, R3+).
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = (client)
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* Return = A pointer to a filled out SizeHints structure is returned.
|
||
* Default values are set if the WM_NORMAL_HINTS property could
|
||
* not be retrieved.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
SizeHints *
|
||
GetNormalHints(
|
||
ClientData *pCD )
|
||
|
||
{
|
||
PropSizeHints *property = NULL;
|
||
Atom actualType;
|
||
int actualFormat;
|
||
unsigned long leftover;
|
||
unsigned long nitems;
|
||
|
||
|
||
/*
|
||
* Retrieve the property data.
|
||
*
|
||
* ICCC_R2 version: nitems = PROP_SIZE_HINTS_ELEMENTS - 3
|
||
* ICCC_CURRENT version: nitems = PROP_SIZE_HINTS_ELEMENTS
|
||
*/
|
||
|
||
if ((!HasProperty (pCD, XA_WM_NORMAL_HINTS)) ||
|
||
((Success != XGetWindowProperty (DISPLAY, pCD->client,
|
||
XA_WM_NORMAL_HINTS, 0L, (long)PROP_SIZE_HINTS_ELEMENTS,
|
||
False, XA_WM_SIZE_HINTS, &actualType, &actualFormat,
|
||
&nitems, &leftover, (unsigned char **)&property)) ||
|
||
(actualType != XA_WM_SIZE_HINTS) ||
|
||
(nitems < (PROP_SIZE_HINTS_ELEMENTS - 3)) ||
|
||
(actualFormat != 32)))
|
||
{
|
||
/*
|
||
* Indicate no property values were retrieved:
|
||
*/
|
||
|
||
sizeHints.icccVersion = ICCC_UNKNOWN;
|
||
sizeHints.flags = 0;
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* Parse the hint values out of the property data:
|
||
*/
|
||
|
||
sizeHints.flags = property->flags;
|
||
sizeHints.x = property->x;
|
||
sizeHints.y = property->y;
|
||
sizeHints.width = property->width;
|
||
sizeHints.height = property->height;
|
||
sizeHints.min_width = property->minWidth;
|
||
sizeHints.min_height = property->minHeight;
|
||
sizeHints.max_width = property->maxWidth;
|
||
sizeHints.max_height = property->maxHeight;
|
||
sizeHints.width_inc = property->widthInc;
|
||
sizeHints.height_inc = property->heightInc;
|
||
sizeHints.min_aspect.x = (int)property->minAspectX;
|
||
sizeHints.min_aspect.y = (int)property->minAspectY;
|
||
sizeHints.max_aspect.x = (int)property->maxAspectX;
|
||
sizeHints.max_aspect.y = (int)property->maxAspectY;
|
||
|
||
|
||
if (nitems == (PROP_SIZE_HINTS_ELEMENTS - 3))
|
||
{
|
||
/*
|
||
* This is ICCC_R2.
|
||
*/
|
||
|
||
sizeHints.icccVersion = ICCC_R2;
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* This is ICCC_CURRENT.
|
||
*/
|
||
|
||
sizeHints.icccVersion = ICCC_CURRENT;
|
||
sizeHints.base_width = property->baseWidth;
|
||
sizeHints.base_height = property->baseHeight;
|
||
sizeHints.win_gravity = property->winGravity;
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
* Free the property data buffer:
|
||
*/
|
||
|
||
if (property)
|
||
{
|
||
XFree ((char *)property);
|
||
}
|
||
|
||
|
||
/*
|
||
* Return the hints values:
|
||
*/
|
||
|
||
return (&sizeHints);
|
||
|
||
|
||
} /* END OF FUNCTION GetNormalHints */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* ProcessWmProtocols (pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function reads and processes the WM_PROTOCOLS property that is
|
||
* associated with a client window.
|
||
*
|
||
* ICCC_COMPLIANT check added to allow older clients to work, for now...
|
||
* eventually, this code should be removed.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* pCD = (clientProtocols, clientProtocolCount, protocolFlags)
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void ProcessWmProtocols (ClientData *pCD)
|
||
{
|
||
int rValue;
|
||
Atom *property = NULL;
|
||
#ifndef ICCC_COMPLIANT
|
||
Atom actualType;
|
||
int actualFormat;
|
||
unsigned long leftover;
|
||
unsigned long nitems;
|
||
#else
|
||
int nitems;
|
||
#endif /* ICCC_COMPLIANT */
|
||
int i;
|
||
|
||
|
||
if (pCD->clientProtocols)
|
||
{
|
||
XtFree ((char *)pCD->clientProtocols);
|
||
pCD->clientProtocols = NULL;
|
||
}
|
||
pCD->clientProtocolCount = 0;
|
||
pCD->protocolFlags = 0;
|
||
|
||
|
||
/*
|
||
* Read the WM_PROTOCOLS property.
|
||
*/
|
||
|
||
#ifndef ICCC_COMPLIANT
|
||
if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
|
||
rValue = -1;
|
||
else
|
||
rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_WM_PROTOCOLS, 0L,
|
||
(long)MAX_CLIENT_PROTOCOL_COUNT, False, AnyPropertyType,
|
||
&actualType, &actualFormat, &nitems, &leftover,
|
||
(unsigned char **)&property);
|
||
|
||
|
||
if ((rValue != Success) || (actualType == None) || (actualFormat != 32))
|
||
#else
|
||
if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
|
||
rValue = -1;
|
||
else
|
||
rValue = XGetWMProtocols (DISPLAY, pCD->client,
|
||
(Atom **)&property, &nitems);
|
||
|
||
if (0 == rValue)
|
||
#endif /* ICCC_COMPLIANT */
|
||
{
|
||
/*
|
||
* WM_PROTOCOLS does not exist or it is an invalid type or size.
|
||
*/
|
||
|
||
pCD->clientProtocols = NULL;
|
||
}
|
||
else
|
||
{
|
||
if (!(pCD->clientProtocols = (Atom *)XtMalloc (nitems * sizeof (Atom))))
|
||
{
|
||
/* unable to allocate space */
|
||
Warning (((char *)GETMESSAGE(54, 1, "Insufficient memory for window management data")));
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* Save the protocols in the client data and look for predefined
|
||
* protocols.
|
||
*/
|
||
|
||
pCD->clientProtocolCount = nitems;
|
||
|
||
for (i = 0; i < nitems; i++)
|
||
{
|
||
pCD->clientProtocols[i] = property[i];
|
||
if (property[i] == wmGD.xa_WM_SAVE_YOURSELF)
|
||
{
|
||
pCD->protocolFlags |= PROTOCOL_WM_SAVE_YOURSELF;
|
||
}
|
||
else if (property[i] == wmGD.xa_WM_TAKE_FOCUS)
|
||
{
|
||
pCD->protocolFlags |= PROTOCOL_WM_TAKE_FOCUS;
|
||
}
|
||
else if (property[i] == wmGD.xa_WM_DELETE_WINDOW)
|
||
{
|
||
pCD->protocolFlags |= PROTOCOL_WM_DELETE_WINDOW;
|
||
}
|
||
else if (property[i] == wmGD.xa_MWM_MESSAGES)
|
||
{
|
||
pCD->protocolFlags |= PROTOCOL_MWM_MESSAGES;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
if (property)
|
||
{
|
||
XFree ((char *)property);
|
||
}
|
||
|
||
|
||
} /* END OF FUNCTION ProcessWmProtocols */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* ProcessMwmMessages (pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function reads and processes the _MWM_MESSAGES property that is
|
||
* associated with a client window.
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* pCD = (mwmMessagesCount, mwmMessages)
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void ProcessMwmMessages (ClientData *pCD)
|
||
{
|
||
int rValue;
|
||
long *property = NULL;
|
||
Atom actualType;
|
||
int actualFormat;
|
||
unsigned long leftover;
|
||
unsigned long nitems;
|
||
int i;
|
||
|
||
|
||
if (pCD->mwmMessages)
|
||
{
|
||
XtFree ((char *)pCD->mwmMessages);
|
||
pCD->mwmMessages = NULL;
|
||
}
|
||
pCD->mwmMessagesCount = 0;
|
||
|
||
|
||
/*
|
||
* Read the _MWM_MESSAGES property.
|
||
*/
|
||
|
||
if (!HasProperty (pCD, wmGD.xa_MWM_MESSAGES))
|
||
rValue = ~Success;
|
||
else
|
||
rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_MESSAGES, 0L,
|
||
(long)MAX_MWM_MESSAGES_COUNT, False, AnyPropertyType,
|
||
&actualType, &actualFormat, &nitems, &leftover,
|
||
(unsigned char **)&property);
|
||
|
||
|
||
if ((rValue != Success) || (actualType == None) || (actualFormat != 32)
|
||
|| (nitems == 0))
|
||
{
|
||
/*
|
||
* _MWM_MESSAGES does not exist or it is an invalid type.
|
||
*/
|
||
|
||
pCD->mwmMessages = NULL;
|
||
}
|
||
else
|
||
{
|
||
if (!(pCD->mwmMessages = (long *)XtMalloc (nitems * sizeof (long))))
|
||
{
|
||
/* unable to allocate space */
|
||
Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* Save the protocols in the client data and look for predefined
|
||
* protocols.
|
||
*/
|
||
|
||
pCD->mwmMessagesCount = nitems;
|
||
|
||
for (i = 0; i < nitems; i++)
|
||
{
|
||
if ((pCD->mwmMessages[i] = property[i]) == wmGD.xa_MWM_OFFSET)
|
||
{
|
||
pCD->protocolFlags |= PROTOCOL_MWM_OFFSET;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
if (property)
|
||
{
|
||
XFree ((char *)property);
|
||
}
|
||
|
||
|
||
} /* END OF FUNCTION ProcessMwmMessages */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* SetMwmInfo (propWindow, flags, wmWindow)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function sets up the _MOTIF_WM_INFO property on the specified (usually
|
||
* the root) window.
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* propWindow = window on which the _MOTIF_WM_INFO property is to be set
|
||
*
|
||
* flags = motifWmInfo.flags value
|
||
*
|
||
* wmWindow = motifWmInfo.wmWindow value
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* _MWM_INFO = this property is set on the specified window
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void SetMwmInfo (Window propWindow, long flags, Window wmWindow)
|
||
{
|
||
PropMwmInfo property;
|
||
|
||
|
||
property.flags = flags;
|
||
property.wmWindow = wmWindow;
|
||
|
||
XChangeProperty (DISPLAY, propWindow, wmGD.xa_MWM_INFO, wmGD.xa_MWM_INFO,
|
||
32, PropModeReplace, (unsigned char *)&property,
|
||
PROP_MWM_INFO_ELEMENTS);
|
||
|
||
} /* END OF FUNCTION SetMwmInfo */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* SetMwmSaveSessionInfo (wmWindow)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function sets up the WM_SAVE_YOURSELF property on the wm window
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* wmWindow = motifWmInfo.wmWindow
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* WM_SAVE_YOURSELF = this property is set on the wm window
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void SetMwmSaveSessionInfo (Window wmWindow)
|
||
{
|
||
|
||
Atom property;
|
||
property = wmGD.xa_WM_SAVE_YOURSELF;
|
||
|
||
XChangeProperty (DISPLAY, wmWindow,
|
||
wmGD.xa_WM_PROTOCOLS, XA_ATOM,
|
||
32, PropModeReplace,
|
||
(unsigned char *) &property, 1);
|
||
SetWMState(wmWindow, NORMAL_STATE, 0);
|
||
|
||
} /* END OF FUNCTION SetMwmSaveSessionInfo */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* GetWMState (window)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function gets the WM_STATE property on a client top-level
|
||
* window.
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* window = client window from which the WM_STATE property is to be retrieved
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* RETURN = a pointer to the WM_STATE property value (NULL if not defined)
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
* This function will eventually be superseded when WM_STATE support is
|
||
* added to the official X release.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
PropWMState *
|
||
GetWMState(
|
||
Window window )
|
||
{
|
||
int ret_val;
|
||
PropWMState *property = NULL;
|
||
Atom actual_type;
|
||
int actual_format;
|
||
unsigned long nitems;
|
||
unsigned long leftover;
|
||
|
||
|
||
ret_val = XGetWindowProperty (DISPLAY, window, wmGD.xa_WM_STATE,
|
||
0L, PROP_WM_STATE_ELEMENTS,
|
||
False, wmGD.xa_WM_STATE,
|
||
&actual_type, &actual_format,
|
||
&nitems, &leftover, (unsigned char **)&property);
|
||
|
||
if (!((ret_val == Success) && (actual_type == wmGD.xa_WM_STATE) &&
|
||
(nitems == PROP_WM_STATE_ELEMENTS)))
|
||
{
|
||
/*
|
||
* The property could not be retrieved or is not correctly set up.
|
||
*/
|
||
|
||
if (property)
|
||
{
|
||
XFree ((char *)property);
|
||
property = NULL;
|
||
}
|
||
}
|
||
|
||
return (property);
|
||
|
||
} /* END OF FUNCTION GetWMState */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* SetWMState (window, state, icon)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function sets up the WM_STATE property on a client top-level
|
||
* window.
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* window = client window on which the WM_STATE property is to be set
|
||
*
|
||
* state = state of the client application
|
||
*
|
||
* icon = window manager's icon window
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* WM_STATE = this property is set on the client window
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
* This function will eventually be superseded when WM_STATE support is
|
||
* added to the official X release.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void SetWMState (Window window, int state, Window icon)
|
||
{
|
||
PropWMState property;
|
||
|
||
|
||
property.state = state;
|
||
property.icon = icon;
|
||
|
||
XChangeProperty (DISPLAY, window, wmGD.xa_WM_STATE, wmGD.xa_WM_STATE, 32,
|
||
PropModeReplace, (unsigned char *)&property, PROP_WM_STATE_ELEMENTS);
|
||
|
||
} /* END OF FUNCTION SetWMState */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* PropMwmHints *
|
||
* GetMwmHints (pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function reads any _MWM_HINTS property that is associated with a
|
||
* client window.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* RETURN = ptr to mwm hints property, or NULL ptr if failure
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
PropMwmHints *
|
||
GetMwmHints(
|
||
ClientData *pCD )
|
||
|
||
{
|
||
int ret_val;
|
||
PropMwmHints *property = NULL;
|
||
Atom actual_type;
|
||
int actual_format;
|
||
unsigned long nitems;
|
||
unsigned long leftover;
|
||
|
||
|
||
if (!HasProperty(pCD, wmGD.xa_MWM_HINTS))
|
||
ret_val = ~Success;
|
||
else
|
||
ret_val = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_HINTS,
|
||
0L, PROP_MWM_HINTS_ELEMENTS,
|
||
False, wmGD.xa_MWM_HINTS,
|
||
&actual_type, &actual_format,
|
||
&nitems, &leftover, (unsigned char **)&property);
|
||
|
||
/*
|
||
* Retrieve the property data.
|
||
*
|
||
* Motif 1.1.n clients: nitems = PROP_MWM_HINTS_ELEMENTS
|
||
* Motif 1.2 clients: nitems = PROP_MWM_HINTS_ELEMENTS + 2
|
||
*
|
||
* NOTES: We don't need to check (nitems == PROP_MWM_HINTS_ELEMENTS)
|
||
* since...
|
||
*
|
||
* If running Motif 1.1.n client with Mwm 1.2, then ignore extra elements
|
||
* since property.flags won't have extra elements set.
|
||
*
|
||
* If running Motif 1.2 client with Mwm 1.1.n, then ignore extra elements
|
||
* since Mwm 1.1.n won't try to access the extra elements.
|
||
*/
|
||
|
||
if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_HINTS))
|
||
{
|
||
return (property); /* indicate success */
|
||
}
|
||
|
||
|
||
/*
|
||
* The property could not be retrieved or is not correctly set up.
|
||
*/
|
||
|
||
if (property)
|
||
{
|
||
XFree ((char *)property);
|
||
}
|
||
|
||
return (NULL); /* indicate failure */
|
||
|
||
|
||
} /* END OF FUNCTION GetMwmHints */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* PropMwmInfo *
|
||
* GetMwmInfo (rootWindowOfScreen)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function reads the _MOTIF_WM_INFO property from the root window if
|
||
* it is setup.
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pSD = pointer to screen data
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* RETURN = ptr to motif wm info property, or NULL ptr if no property
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
PropMwmInfo *GetMwmInfo (Window rootWindowOfScreen)
|
||
{
|
||
int ret_val;
|
||
PropMwmInfo *property = NULL;
|
||
Atom actual_type;
|
||
int actual_format;
|
||
unsigned long nitems;
|
||
unsigned long leftover;
|
||
|
||
|
||
ret_val = XGetWindowProperty (DISPLAY, rootWindowOfScreen,
|
||
wmGD.xa_MWM_INFO,
|
||
0L, PROP_MWM_INFO_ELEMENTS,
|
||
False, wmGD.xa_MWM_INFO,
|
||
&actual_type, &actual_format,
|
||
&nitems, &leftover,
|
||
(unsigned char **)&property);
|
||
|
||
if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_INFO) &&
|
||
(nitems == PROP_MWM_INFO_ELEMENTS))
|
||
{
|
||
return (property); /* indicate success */
|
||
}
|
||
|
||
|
||
/*
|
||
* The property could not be retrieved or is not correctly set up.
|
||
*/
|
||
|
||
if (property)
|
||
{
|
||
XFree ((char *)property);
|
||
}
|
||
|
||
return (NULL); /* indicate failure */
|
||
|
||
|
||
} /* END OF FUNCTION GetMwmInfo */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* ProcessWmColormapWindows (pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function retrieves and processes the WM_COLORMAP_WINDOWS client
|
||
* window property.
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* pCD = (cmapWindows, clientCmapList, clientCmapCount, clientCmapIndex)
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void ProcessWmColormapWindows (ClientData *pCD)
|
||
{
|
||
int rValue;
|
||
Window *property = NULL;
|
||
Atom actualType;
|
||
int actualFormat;
|
||
unsigned long leftover;
|
||
unsigned long nitems;
|
||
int i;
|
||
Window *pWindows;
|
||
Colormap *pColormaps;
|
||
int colormapCount;
|
||
XWindowAttributes wAttributes;
|
||
ClientData *pcd;
|
||
XSetWindowAttributes sAttributes;
|
||
int *pCmapFlags;
|
||
|
||
|
||
/*
|
||
* pCD->clientCmapCount and pCD->clientCmapIndex are initialized in
|
||
* WmWinInfo.c.
|
||
*/
|
||
|
||
/*
|
||
* Read the WM_COLORMAP_WINDOWS property.
|
||
*/
|
||
|
||
rValue = XGetWindowProperty (DISPLAY, pCD->client,
|
||
wmGD.xa_WM_COLORMAP_WINDOWS, 0L,
|
||
(long)MAX_COLORMAP_WINDOWS_COUNT, False, AnyPropertyType,
|
||
&actualType, &actualFormat, &nitems, &leftover,
|
||
(unsigned char **)&property);
|
||
|
||
|
||
if ((rValue == Success) && (actualType != None) && (actualFormat == 32) &&
|
||
(nitems > 0))
|
||
{
|
||
/*
|
||
* WM_COLORMAP_WINDOWS exists and is a valid type.
|
||
*/
|
||
|
||
if (!(pWindows = (Window *)XtMalloc ((nitems * sizeof (Window)) + 1)) ||
|
||
!(pColormaps = (Colormap *)XtMalloc ((nitems*sizeof(Colormap)) + 1)))
|
||
{
|
||
/* unable to allocate space */
|
||
Warning (((char *)GETMESSAGE(54, 3, "Insufficient memory for window management data")));
|
||
if (pWindows)
|
||
{
|
||
XtFree ((char *)pWindows);
|
||
}
|
||
}
|
||
/* Is the above OSF code a bug -- allocates one extra byte, rather */
|
||
/* than one extra element, for the top window if needed? */
|
||
else if ( ! (pCmapFlags = (int *)XtCalloc(nitems+1,sizeof(int)))) {
|
||
/* unable to allocate space */
|
||
Warning (((char *)GETMESSAGE(54, 4, "Insufficient memory for window manager flags")));
|
||
XtFree ((char *)pWindows); XtFree ((char *)pColormaps);
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* Check to see if the top-level client window is in the list.
|
||
* If it is not then add it to the head of the list.
|
||
*/
|
||
|
||
for (i = 0; i < nitems; i++)
|
||
{
|
||
if (property[i] == pCD->client)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
colormapCount = 0;
|
||
if (i == nitems)
|
||
{
|
||
/* add the client window to the colormap window list */
|
||
pWindows[0] = pCD->client;
|
||
pColormaps[0] = FindColormap (pCD, pCD->client);
|
||
colormapCount++;
|
||
}
|
||
|
||
sAttributes.event_mask = (ColormapChangeMask);
|
||
for (i = 0; i < nitems; i++)
|
||
{
|
||
if ((pColormaps[colormapCount] =
|
||
FindColormap (pCD, property[i])) != None)
|
||
{
|
||
pWindows[colormapCount] = property[i];
|
||
colormapCount++;
|
||
}
|
||
else if (XFindContext (DISPLAY, property[i],
|
||
wmGD.windowContextType, (caddr_t *)&pcd))
|
||
{
|
||
/*
|
||
* The window is not a top level window or a window that
|
||
* is already being tracked for colormap changes.
|
||
* Track colormap attribute changes.
|
||
*/
|
||
|
||
XChangeWindowAttributes (DISPLAY, property[i], CWEventMask,
|
||
&sAttributes);
|
||
|
||
|
||
if (XGetWindowAttributes (DISPLAY, property[i],
|
||
&wAttributes))
|
||
{
|
||
pWindows[colormapCount] = property[i];
|
||
pColormaps[colormapCount] = wAttributes.colormap;
|
||
colormapCount++;
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Free up the old colormap window data if it has been set. Set
|
||
* new window contexts.
|
||
*/
|
||
|
||
ResetColormapData (pCD, pWindows, colormapCount);
|
||
|
||
|
||
/*
|
||
* Set the colormap window data.
|
||
*/
|
||
|
||
pCD->clientColormap = pColormaps[0];
|
||
if (colormapCount > 1)
|
||
{
|
||
/*
|
||
* The top level window and at least one other window is in
|
||
* the colormap windows list.
|
||
*/
|
||
|
||
pCD->clientCmapCount = colormapCount;
|
||
pCD->cmapWindows = pWindows;
|
||
pCD->clientCmapList = pColormaps;
|
||
pCD->clientCmapIndex = 0;
|
||
pCD->clientCmapFlags = pCmapFlags;
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* Only the top level window is being tracked for colormap
|
||
* data.
|
||
*/
|
||
|
||
pCD->clientCmapCount = 0;
|
||
XtFree ((char *)pWindows);
|
||
XtFree ((char *)pColormaps);
|
||
XtFree((char *)pCmapFlags);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
if (property)
|
||
{
|
||
XFree ((char *)property);
|
||
}
|
||
|
||
|
||
} /* END OF FUNCTION ProcessWmColormapWindows */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* FindColormap (pCD, window)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function checks colormap information that is currently saved in
|
||
* the client data for the colormap of the specified window.
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
* window = get the colormap id for this window
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* RETURN = colormap id for window (NULL if no colormap information)
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Colormap FindColormap (ClientData *pCD, Window window)
|
||
{
|
||
Colormap colormap = (Colormap)0;
|
||
int i;
|
||
|
||
|
||
if (pCD->clientCmapCount == 0)
|
||
{
|
||
/*
|
||
* If the colormap count is 0 there is no list of colormaps and
|
||
* clientColormap is the colormap of the top-level window.
|
||
*/
|
||
|
||
if (window == pCD->client)
|
||
{
|
||
colormap = pCD->clientColormap;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (i = 0; i < pCD->clientCmapCount; i++)
|
||
{
|
||
if (pCD->cmapWindows[i] == window)
|
||
{
|
||
colormap = pCD->clientCmapList[i];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return (colormap);
|
||
|
||
} /* END OF FUNCTION FindColormap */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* GetMwmMenuItems (pCD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function reads and processes any _MWM_MENU property that is
|
||
* associated with a client window and returns a list of MenuItem structures
|
||
* specified by the property, or NULL.
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD = pointer to client data
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* Return = MenuItem list or NULL.
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
MenuItem *
|
||
GetMwmMenuItems(
|
||
ClientData *pCD )
|
||
{
|
||
int rValue;
|
||
XTextProperty textProperty;
|
||
MenuItem *menuItems;
|
||
|
||
/*
|
||
* Read the _MWM_MENU property.
|
||
*/
|
||
|
||
textProperty.value = (unsigned char *)NULL;
|
||
rValue = XGetTextProperty(DISPLAY, pCD->client, &textProperty,
|
||
wmGD.xa_MWM_MENU);
|
||
if ((rValue == 0) || (textProperty.value == (unsigned char *)NULL))
|
||
/* _MWM_MENU does not exist or it is an invalid type. */
|
||
{
|
||
menuItems = NULL;
|
||
}
|
||
|
||
else
|
||
/* parse the property string */
|
||
{
|
||
char **textList;
|
||
int nItems;
|
||
|
||
if (XmbTextPropertyToTextList(DISPLAY, &textProperty,
|
||
&textList, &nItems) != Success)
|
||
{
|
||
menuItems = NULL;
|
||
}
|
||
else
|
||
{
|
||
menuItems = ParseMwmMenuStr (PSD_FOR_CLIENT(pCD),
|
||
(unsigned char *)textList[0]);
|
||
XFreeStringList(textList);
|
||
}
|
||
|
||
XFree((void *)textProperty.value);
|
||
}
|
||
|
||
return (menuItems);
|
||
|
||
} /* END OF FUNCTION GetMwmMenuItems */
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* GetWorkspaceHints (display, window, ppWsAtoms, pCount, pbAll)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Get the contents of the WM_COMMAND property on a window
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* display - X display
|
||
* window - window to get hints from
|
||
* ppWsAtoms - pointer to a list of workspace atoms (to be returned)
|
||
* pCount - ptr to a number of atoms (to be returned)
|
||
* pbAll - ptr to a boolean (to be returned)
|
||
*
|
||
*
|
||
* Returns:
|
||
* --------
|
||
* Success if suceeded, otherwise failure code.
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* *ppWsAtoms - list of workspace atoms
|
||
* *pCount - number of atoms in *ppWsAtoms
|
||
* *pbAll - True if should put in all workspaces
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
* The caller must XtFree *ppWsAtoms when done!!!
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Status GetWorkspaceHints (Display *display, Window window,
|
||
Atom **ppWsAtoms, unsigned int *pCount,
|
||
Boolean *pbAll)
|
||
{
|
||
int rcode;
|
||
DtWorkspaceHints *pWsHints;
|
||
Atom *paWs;
|
||
|
||
rcode = _DtWsmGetWorkspaceHints(display, window, &pWsHints);
|
||
if (rcode == Success)
|
||
{
|
||
if (pWsHints->flags & DT_WORKSPACE_HINTS_WORKSPACES)
|
||
{
|
||
paWs = (Atom *)
|
||
XtMalloc (pWsHints->numWorkspaces * sizeof(Atom));
|
||
memcpy (paWs,
|
||
pWsHints->pWorkspaces,
|
||
(pWsHints->numWorkspaces * sizeof(Atom)));
|
||
|
||
*pCount = pWsHints->numWorkspaces;
|
||
*ppWsAtoms = paWs;
|
||
}
|
||
else
|
||
{
|
||
*pCount = 0;
|
||
*ppWsAtoms = NULL;
|
||
}
|
||
|
||
if ((pWsHints->flags & DT_WORKSPACE_HINTS_WSFLAGS) &&
|
||
(pWsHints->wsflags & DT_WORKSPACE_FLAGS_OCCUPY_ALL))
|
||
{
|
||
*pbAll = True;
|
||
}
|
||
else
|
||
{
|
||
*pbAll = False;
|
||
}
|
||
|
||
|
||
_DtWsmFreeWorkspaceHints (pWsHints);
|
||
}
|
||
|
||
return(rcode);
|
||
|
||
} /* END OF FUNCTION GetWorkspaceHints */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* SetEmbeddedClientsProperty (propWindow, pEmbeddedClients,
|
||
* cEmbeddedCLients)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function writes the _DT_WORKSPACE_EMBEDDED_CLIENTS property
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* propWindow = window on which the property is to be written
|
||
* pEmbeddedClients = pointer to data (array of window IDs)
|
||
* cEmbeddedClients = number of window IDs in the array
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void SetEmbeddedClientsProperty (Window propWindow,
|
||
Window *pEmbeddedClients, unsigned long cEmbeddedClients)
|
||
{
|
||
XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_EMBEDDED_CLIENTS,
|
||
wmGD.xa_DT_EMBEDDED_CLIENTS,
|
||
32, PropModeReplace, (unsigned char *)pEmbeddedClients,
|
||
cEmbeddedClients);
|
||
|
||
} /* END OF FUNCTION SetEmbeddedClientsProperty */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* SetWorkspaceListProperty (pSD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function sets up the _DT_WORKSPACE_LIST property
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pSD = ptr to screen data
|
||
*
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
SetWorkspaceListProperty (WmScreenData *pSD)
|
||
{
|
||
WmWorkspaceData *pws;
|
||
Atom *pWsList;
|
||
int count;
|
||
|
||
pWsList = (Atom *)
|
||
XtMalloc (pSD->numWorkspaces * sizeof(Atom));
|
||
|
||
pws = pSD->pWS;
|
||
for (count = 0; count < pSD->numWorkspaces; count++)
|
||
{
|
||
pWsList[count] = pws->id;
|
||
pws++;
|
||
}
|
||
|
||
XChangeProperty (DISPLAY, pSD->wmWorkspaceWin,
|
||
wmGD.xa_DT_WORKSPACE_LIST,
|
||
XA_ATOM,
|
||
32, PropModeReplace, (unsigned char *)pWsList,
|
||
(pSD->numWorkspaces * sizeof(Atom))/sizeof(long));
|
||
|
||
XtFree ((char *) pWsList);
|
||
|
||
} /* END OF FUNCTION SetWorkspaceListProperty */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* SetCurrentWorkspaceProperty (pSD)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function sets up the _DT_WORKSPACE_CURRENT property
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pSD = ptr to screen data
|
||
*
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
SetCurrentWorkspaceProperty (WmScreenData *pSD)
|
||
{
|
||
Atom aCurrent;
|
||
|
||
aCurrent = pSD->pActiveWS->id;
|
||
|
||
XChangeProperty (DISPLAY, pSD->wmWorkspaceWin,
|
||
wmGD.xa_DT_WORKSPACE_CURRENT,
|
||
XA_ATOM,
|
||
32, PropModeReplace, (unsigned char *)&aCurrent,
|
||
(sizeof(Atom))/sizeof(long));
|
||
|
||
XSync (DISPLAY, False); /* XFlush didn't work here, why? */
|
||
|
||
} /* END OF FUNCTION SetCurrentWorkspaceProperty */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* SetWorkspaceInfoProperty (pWS)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function sets up the _DT_WORKSPACE_INFO_<name> property
|
||
* for a particular workspace
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pWS = ptr to workspace data
|
||
*
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
SetWorkspaceInfoProperty (WmWorkspaceData *pWS)
|
||
{
|
||
char *pch;
|
||
Atom aProperty;
|
||
String sTitle;
|
||
char **ppchList;
|
||
int iNumStrings;
|
||
int count;
|
||
int i, ix;
|
||
Status status;
|
||
XTextProperty tp;
|
||
#define WIP_NUMBER_SIZE 16
|
||
|
||
/*
|
||
* Construct our property name
|
||
*/
|
||
pch = WorkspacePropertyName (pWS);
|
||
|
||
aProperty = XmInternAtom (DISPLAY, pch, FALSE);
|
||
|
||
XtFree ((char *) pch);
|
||
|
||
/*
|
||
* Determine the number of strings in our vector. One for each of
|
||
*
|
||
* workspace title
|
||
* pixel set id
|
||
* backdrop background
|
||
* backdrop foreground
|
||
* backdrop name
|
||
* number of backdrop windows
|
||
* list of backdrop windows
|
||
*/
|
||
iNumStrings = 7; /* number of fields minus backdrop window(s) */
|
||
count = 1; /* number of backdrop windows */
|
||
iNumStrings += count;
|
||
|
||
/* allocate string vector */
|
||
ppchList = (char **) XtMalloc (iNumStrings * sizeof (char *));
|
||
pch = (char *) XtMalloc (iNumStrings * WIP_NUMBER_SIZE * sizeof(char));
|
||
|
||
i = 0;
|
||
|
||
/* Convert workspace title to ascii */
|
||
sTitle = (String) WmXmStringToString (pWS->title);
|
||
ppchList[i++] = (char *) sTitle;
|
||
|
||
/* Pixel set id */
|
||
ix = (i * WIP_NUMBER_SIZE);
|
||
sprintf (&pch[ix], "%d", pWS->backdrop.colorSet);
|
||
ppchList[i++] = &pch[ix];
|
||
|
||
/* backdrop background */
|
||
ix = (i * WIP_NUMBER_SIZE);
|
||
sprintf (&pch[ix], "0x%lx", pWS->backdrop.background);
|
||
ppchList[i++] = &pch[ix];
|
||
|
||
/* backdrop foreground */
|
||
ix = (i * WIP_NUMBER_SIZE);
|
||
sprintf (&pch[ix], "0x%lx", pWS->backdrop.foreground);
|
||
ppchList[i++] = &pch[ix];
|
||
|
||
/* backdrop name */
|
||
ix = (i * WIP_NUMBER_SIZE);
|
||
sprintf (&pch[ix], "0x%lx", pWS->backdrop.nameAtom);
|
||
ppchList[i++] = &pch[ix];
|
||
|
||
/* backdrop type */
|
||
ix = (i * WIP_NUMBER_SIZE);
|
||
sprintf (&pch[ix], "%d", pWS->backdrop.imageType);
|
||
ppchList[i++] = &pch[ix];
|
||
|
||
/* number of backdrop windows */
|
||
ix = (i * WIP_NUMBER_SIZE);
|
||
if (pWS->backdrop.window == None)
|
||
{
|
||
strcpy (&pch[ix], "0");
|
||
}
|
||
else
|
||
{
|
||
sprintf (&pch[ix], "%d", count);
|
||
}
|
||
ppchList[i++] = &pch[ix];
|
||
|
||
/* backdrop windows */
|
||
/*
|
||
* One or zero backdrop windows
|
||
* (NULL written if zero)
|
||
*/
|
||
ix = (i * WIP_NUMBER_SIZE);
|
||
sprintf (&pch[ix], "0x%lx", pWS->backdrop.window);
|
||
ppchList[i++] = &pch[ix];
|
||
|
||
/*
|
||
* Write out the property
|
||
*/
|
||
status = XmbTextListToTextProperty (DISPLAY, ppchList, iNumStrings,
|
||
XStdICCTextStyle, &tp);
|
||
if ((status == Success) || (status > 0))
|
||
{
|
||
/*
|
||
* Complete or partial conversion
|
||
*/
|
||
XSetTextProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, &tp, aProperty);
|
||
XFree (tp.value);
|
||
}
|
||
|
||
XtFree ((char *) ppchList);
|
||
XtFree (pch);
|
||
if (sTitle) XtFree ((char *)sTitle);
|
||
|
||
} /* END OF FUNCTION SetWorkspaceInfoProperty */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* DeleteWorkspaceInfoProperty (pWS)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function deletes a _DT_WORKSPACE_INFO_<name> property
|
||
* for a particular workspace
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pWS = ptr to workspace data
|
||
*
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
DeleteWorkspaceInfoProperty (WmWorkspaceData *pWS)
|
||
{
|
||
char *pch;
|
||
Atom aProperty;
|
||
|
||
/*
|
||
* Get the atom for the workspace property.
|
||
*/
|
||
pch = WorkspacePropertyName (pWS);
|
||
|
||
aProperty = XmInternAtom (DISPLAY, pch, FALSE);
|
||
|
||
XtFree ((char *) pch);
|
||
|
||
/*
|
||
* Do the property deletion
|
||
*/
|
||
XDeleteProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, aProperty);
|
||
XFlush (DISPLAY);
|
||
|
||
|
||
} /* END OF FUNCTION DeleteWorkspaceInfoProperty */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* WorkspacePropertyName (pWS)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function returns a string containing the property name for a
|
||
* workspace.
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pWS = ptr to workspace data
|
||
*
|
||
* Returns
|
||
* -------
|
||
* string containing the workspace property name (Free with XtFree)
|
||
*
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
char *
|
||
WorkspacePropertyName (WmWorkspaceData *pWS)
|
||
{
|
||
char *pch;
|
||
char *pchName;
|
||
int len;
|
||
|
||
/*
|
||
* Construct our property name
|
||
*/
|
||
pchName = pWS->name;
|
||
len = strlen(pchName) + strlen (_XA_DT_WORKSPACE_INFO) + 4;
|
||
|
||
pch = (char *) XtMalloc (len);
|
||
strcpy (pch, _XA_DT_WORKSPACE_INFO);
|
||
strcat (pch, "_");
|
||
strcat (pch, pchName);
|
||
|
||
return (pch);
|
||
|
||
} /* END OF FUNCTION WorkspacePropertyName */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* SetWorkspacePresence (propWindow, pWsPresence, cPresence)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function sets up the _DT_WORKSPACE_PRESENCE property
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* propWindow = window on which the _DT_WORKSPACE_PRESENCE property
|
||
* is to be set
|
||
* pWsPresence = pointer to workspace presence data
|
||
* cPresence = size of workspace presence data
|
||
*
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void SetWorkspacePresence (Window propWindow, Atom *pWsPresence, unsigned long cPresence)
|
||
{
|
||
XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_WORKSPACE_PRESENCE,
|
||
wmGD.xa_DT_WORKSPACE_PRESENCE, 32, PropModeReplace,
|
||
(unsigned char *)pWsPresence, cPresence);
|
||
XFlush (DISPLAY);
|
||
|
||
} /* END OF FUNCTION SetWorkspacePresence */
|
||
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* GetDtSessionHints (pSD, sNum)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function reads and processes _DT_SESSION_HINTS property that is
|
||
* associated with the root window of each screen managed by dtwm
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void GetDtSessionHints (WmScreenData *pSD, int sNum)
|
||
|
||
{
|
||
|
||
int rValue;
|
||
char *property = NULL;
|
||
Atom actualType;
|
||
int actualFormat;
|
||
unsigned long leftover;
|
||
unsigned long nitems;
|
||
|
||
|
||
|
||
/*
|
||
* Read the property.
|
||
*/
|
||
|
||
rValue = XGetWindowProperty (DISPLAY, pSD->rootWindow,
|
||
wmGD.xa_DT_SESSION_HINTS, 0L,
|
||
(long)1000000, False, AnyPropertyType,
|
||
&actualType, &actualFormat, &nitems,
|
||
&leftover, (unsigned char **)&property);
|
||
|
||
|
||
if ((rValue != Success) || (actualType == None) || (actualFormat != 8))
|
||
/* _DT_SESSION_HINTS does not exist or it is an invalid type. */
|
||
{
|
||
pSD->pDtSessionItems = NULL;
|
||
|
||
}
|
||
|
||
else
|
||
/* parse the property string */
|
||
{
|
||
ParseDtSessionHints (pSD, (unsigned char *)property);
|
||
}
|
||
|
||
|
||
if (property)
|
||
{
|
||
XFree ((char *)property);
|
||
}
|
||
|
||
/*
|
||
* Delete the property so we don't see it if the user
|
||
* restarts dtwm.
|
||
*/
|
||
#ifndef DEBUG_SESSION_HINTS
|
||
XDeleteProperty (DISPLAY, pSD->rootWindow, wmGD.xa_DT_SESSION_HINTS);
|
||
#endif /* DEBUG_SESSION_HINTS */
|
||
} /* END OF FUNCTION GetDtSessionHints */
|
||
|
||
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* GetDtWmRequest (pSD, pszReq, pmore)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* This function returns the next request
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pSD - pointer to screen data
|
||
* psdReq - pointer to a char pointer
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* *pszReq - pointer to null terminated string containing next
|
||
* request
|
||
* *pmore - set to true if more data is left in the property
|
||
*
|
||
* Comments:
|
||
* ---------
|
||
* The data for pszReq is allocated in here. The caller must free up
|
||
* this space using XtFree.
|
||
*
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
GetDtWmRequest (
|
||
WmScreenData *pSD,
|
||
char **pszReq,
|
||
Boolean *pmore)
|
||
|
||
{
|
||
|
||
int rValue;
|
||
char *chRequest = NULL;
|
||
static char *property = NULL;
|
||
static int iNext = -1;
|
||
int i;
|
||
Atom actualType;
|
||
int actualFormat;
|
||
unsigned long leftover;
|
||
static unsigned long nitems = 0;
|
||
|
||
|
||
/*
|
||
* We need to read the property again if we have no data left
|
||
* over from last time;
|
||
*/
|
||
if (property == NULL)
|
||
{
|
||
/*
|
||
* Read the property and delete it.
|
||
*/
|
||
rValue = XGetWindowProperty (DISPLAY, pSD->wmWorkspaceWin,
|
||
wmGD.xa_DT_WM_REQUEST, 0L,
|
||
(long)1000000, True, AnyPropertyType,
|
||
&actualType, &actualFormat, &nitems,
|
||
&leftover, (unsigned char **)&property);
|
||
|
||
/*
|
||
* Validate the property that we've read
|
||
*/
|
||
if ((rValue != Success) ||
|
||
(actualType == None) ||
|
||
(actualFormat != 8))
|
||
{
|
||
/* The property does not exist or it is an invalid type. */
|
||
property = NULL;
|
||
iNext = -1;
|
||
nitems = 0;
|
||
}
|
||
else
|
||
{
|
||
/* the property is fine, set the index of the next char. */
|
||
iNext = 0;
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
* If we've got something, then extract and return the next
|
||
* request.
|
||
*/
|
||
if (property && iNext >= 0)
|
||
{
|
||
int len = 0;
|
||
|
||
for (i=iNext; i<nitems; i++)
|
||
{
|
||
if (property [i] == '\0')
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
if (i>=nitems) i=nitems;
|
||
|
||
len = i - iNext + 1 + ((property[i] == '\0') ? 0 : 1);
|
||
|
||
chRequest = (char *) XtMalloc (len);
|
||
if (chRequest == NULL)
|
||
{
|
||
Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
|
||
}
|
||
else
|
||
{
|
||
/* dequeue the request */
|
||
strncpy (chRequest, &property[iNext], len);
|
||
if (property[i] != '\0')
|
||
{
|
||
chRequest[len-1]='\0';
|
||
}
|
||
iNext = i+1;
|
||
}
|
||
|
||
if (iNext >= nitems)
|
||
{
|
||
/*
|
||
* Extracted the last request, free up the storage
|
||
* and reset for next time.
|
||
*/
|
||
XFree ((char *)property);
|
||
iNext = -1;
|
||
property = NULL;
|
||
}
|
||
}
|
||
|
||
*pmore = (property != NULL);
|
||
*pszReq = chRequest;
|
||
|
||
} /* END OF FUNCTION GetDtWmRequest */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* GetIntialPropertyList (ClientData *)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Get the list of initial properties on the window
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD - pointer to client data
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* pCD - paInitialProperties member is updated
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
* The caller must XFree the paIntialialProperties member!
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
GetInitialPropertyList (ClientData *pCD)
|
||
{
|
||
Atom *paList;
|
||
int iProps;
|
||
|
||
paList = XListProperties (DISPLAY, pCD->client, &iProps);
|
||
|
||
if (paList)
|
||
{
|
||
pCD->paInitialProperties = paList;
|
||
pCD->numInitialProperties = iProps;
|
||
}
|
||
else
|
||
{
|
||
pCD->paInitialProperties = NULL;
|
||
pCD->numInitialProperties = 0;
|
||
}
|
||
|
||
} /* END OF FUNCTION GetInitialPropertyList */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* DiscardIntialPropertyList (ClientData *)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Tosses out the intial property list for a client, frees data
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD - pointer to client data
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* pCD - paInitialProperties member is updated
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
void
|
||
DiscardInitialPropertyList (ClientData *pCD)
|
||
{
|
||
if (pCD->paInitialProperties)
|
||
{
|
||
/*
|
||
* Free the initial property list.
|
||
* (see HasProperty() function)
|
||
*/
|
||
XFree ((char *) pCD->paInitialProperties);
|
||
pCD->paInitialProperties = NULL;
|
||
pCD->numInitialProperties = 0;
|
||
}
|
||
} /* END OF FUNCTION DiscardInitialPropertyList */
|
||
|
||
|
||
/*************************************<->*************************************
|
||
*
|
||
* HasProperty (pCD, aProperty)
|
||
*
|
||
*
|
||
* Description:
|
||
* -----------
|
||
* Returns True if this client had this property when it was mapped
|
||
*
|
||
*
|
||
* Inputs:
|
||
* ------
|
||
* pCD - pointer to client data
|
||
* aProperty - atom of property to test for
|
||
*
|
||
*
|
||
* Outputs:
|
||
* -------
|
||
* Return - True if this property was on the initial list for this
|
||
* client; False otherwise.
|
||
*
|
||
*
|
||
* Comments:
|
||
* --------
|
||
*
|
||
*************************************<->***********************************/
|
||
|
||
Boolean
|
||
HasProperty (
|
||
ClientData * pCD,
|
||
Atom aProperty)
|
||
{
|
||
Boolean bFound = False;
|
||
Atom * paList;
|
||
int count;
|
||
|
||
paList = pCD->paInitialProperties;
|
||
|
||
if (paList)
|
||
{
|
||
count = pCD->numInitialProperties;
|
||
while ((!bFound) && (count > 0))
|
||
{
|
||
bFound = (*paList == aProperty);
|
||
count--;
|
||
paList++;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
* The property list doesn't exist. Return
|
||
* True to force a read of this property. The most likely
|
||
* case is that this property was updated after the
|
||
* window was managed and needs to be read.
|
||
*/
|
||
bFound = True;
|
||
}
|
||
return (bFound);
|
||
|
||
} /* END OF FUNCTION HasProperty */
|
||
|
||
/**
|
||
* @brief This function calls XGetWindowProperty to get the UTF8_STRING
|
||
* property.
|
||
*
|
||
* @param display
|
||
* @param w
|
||
* @param property
|
||
*
|
||
* @return A string or NULL.
|
||
*/
|
||
char *GetUtf8String (Display *display, Window w, Atom property)
|
||
{
|
||
int actualFormat;
|
||
char *propReturn;
|
||
unsigned long nitems, leftover;
|
||
Atom actualType;
|
||
Atom reqType = wmGD.xa_UTF8_STRING;
|
||
|
||
if (XGetWindowProperty (display, w, property, 0L, USHRT_MAX, False, reqType,
|
||
&actualType, &actualFormat, &nitems, &leftover,
|
||
(unsigned char **) &propReturn) != Success)
|
||
goto err;
|
||
|
||
if (!nitems) goto err;
|
||
if (actualType != reqType) goto err;
|
||
|
||
return propReturn;
|
||
|
||
err:
|
||
if (propReturn) XFree (propReturn);
|
||
return NULL;
|
||
}
|
||
|
||
/**
|
||
* @brief This function calls XChangeProperty to set the UTF8_STRING property.
|
||
*
|
||
* @param display
|
||
* @param w
|
||
* @param property
|
||
* @param s
|
||
*/
|
||
void SetUtf8String (Display *display, Window w, Atom property, const char *s)
|
||
{
|
||
size_t len;
|
||
|
||
if (!(s && s[0])) return;
|
||
|
||
len = strnlen (s, USHRT_MAX);
|
||
|
||
XChangeProperty (display, w, property, wmGD.xa_UTF8_STRING, 8,
|
||
PropModeReplace, (unsigned char *)s, len);
|
||
}
|
||
|
||
/**
|
||
* @brief This function updates _NET_WM_STATE property.
|
||
*
|
||
* @param window
|
||
* @param states
|
||
* @param nstates
|
||
* @param action
|
||
*/
|
||
void UpdateNetWmState (Window window, Atom *states, unsigned long nstates,
|
||
long action)
|
||
{
|
||
int i, j, actualFormat;
|
||
unsigned long nold, leftover;
|
||
Atom actualType;
|
||
unsigned long nnew = 0;
|
||
Atom type = wmGD.xa__NET_WM_STATE;
|
||
Atom *oldStates = NULL;
|
||
Atom *newStates = NULL;
|
||
|
||
if (!states) nstates = 0;
|
||
|
||
if (!(XGetWindowProperty (DISPLAY, window, type, 0L, 1000000L, False,
|
||
XA_ATOM, &actualType, &actualFormat, &nold,
|
||
&leftover, (unsigned char **) &oldStates)
|
||
== Success && actualType == XA_ATOM)) nold = 0;
|
||
|
||
newStates = malloc ((1 + nstates + nold) * sizeof (Atom));
|
||
|
||
if (!newStates) goto done;
|
||
|
||
for (i = 0; i < nold; ++i)
|
||
{
|
||
Atom oldState = oldStates[i];
|
||
for (j = 0; j < nstates; ++j) if (oldState == states[j]) break;
|
||
if (j >= nstates) newStates[nnew++] = oldState;
|
||
}
|
||
|
||
if (action == _NET_WM_STATE_ADD)
|
||
{
|
||
for (i = 0; i < nstates; ++i) newStates[nnew++] = states[i];
|
||
}
|
||
else if (action == _NET_WM_STATE_TOGGLE)
|
||
{
|
||
for (i = 0; i < nstates; ++i)
|
||
{
|
||
Atom state = states[i];
|
||
for (j = 0; j < nold; ++j) if (state == oldStates[j]) break;
|
||
if (j >= nold) newStates[nnew++] = state;
|
||
}
|
||
}
|
||
|
||
XChangeProperty (DISPLAY, window, type, XA_ATOM, 32, PropModeReplace,
|
||
(unsigned char *) newStates, nnew);
|
||
|
||
done:
|
||
if (oldStates) XFree (oldStates);
|
||
if (newStates) free (newStates);
|
||
}
|