/* * @OPENGROUP_COPYRIGHT@ * COPYRIGHT NOTICE * Copyright (c) 1989, 1990, 1991, 1992, 1993 Open Software Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for * the full copyright text. * * This software is subject to an open license. It may only be * used on, with or for operating systems which are themselves open * source systems. You must contact The Open Group for a license * allowing distribution and sublicensing of this software on, with, * or for operating systems which are not Open Source programs. * * See http://www.opengroup.org/openmotif/license for full * details of the license agreement. Any use, reproduction, or * distribution of the program constitutes recipient's acceptance of * this agreement. * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY * OR FITNESS FOR A PARTICULAR PURPOSE * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ /* * Motif Release 1.2.3 */ #ifdef REV_INFO #ifndef lint static char rcsid[] = "$TOG: WmProperty.c /main/7 1997/12/02 10:00:00 bill $" #endif #endif /* * (c) Copyright 1987, 1988, 1989, 1990, 1993 HEWLETT-PACKARD COMPANY */ /* * Included Files: */ #include "WmGlobal.h" #include "WmICCC.h" #include #ifdef WSM #include
#include #endif /* WSM */ /* * include extern functions */ #include "WmColormap.h" #include "WmError.h" #include "WmResParse.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 */ #ifdef WSM 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))) #else /* WSM */ if ((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)) #endif /* WSM */ { /* * 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 #ifdef WSM if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS)) rValue = -1; else #endif /* WSM */ 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 #ifdef WSM if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS)) rValue = -1; else #endif /* WSM */ 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. */ #ifdef WSM if (!HasProperty (pCD, wmGD.xa_MWM_MESSAGES)) rValue = ~Success; else #endif /* WSM */ 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 */ #ifdef WSM /*************************************<->************************************* * * 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 */ #endif /* WSM */ /*************************************<->************************************* * * 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 superceded 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 superceded 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; #ifdef WSM if (!HasProperty(pCD, wmGD.xa_MWM_HINTS)) ret_val = ~Success; else #endif /* WSM */ 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; #ifndef OLD_COLORMAP /* colormaps */ int *pCmapFlags; #endif /* * 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); } } #ifndef OLD_COLORMAP /* colormap */ /* 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); } #endif 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; #ifndef OLD_COLORMAP /* colormap */ pCD->clientCmapFlags = pCmapFlags; #endif } else { /* * Only the top level window is being tracked for colormap * data. */ pCD->clientCmapCount = 0; XtFree ((char *)pWindows); XtFree ((char *)pColormaps); #ifndef OLD_COLORMAP /* colormap */ XtFree((char *)pCmapFlags); #endif } } } 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 */ #ifdef WSM /*************************************<->************************************* * * 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 */ #ifdef HP_VUE /*************************************<->************************************* * * SetWorkspaceInfo (propWindow, pWsInfo, cInfo) * * * Description: * ----------- * This function sets up the _DT_WORKSPACE_INFO property * * * Inputs: * ------ * propWindow = window on which the _DT_WORKSPACE_INFO property is to be set * pWsInfo = pointer to workspace info data * cInfo = size of workspace info data * * *************************************<->***********************************/ void SetWorkspaceInfo (Window propWindow, WorkspaceInfo *pWsInfo, unsigned long cInfo) { XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_WORKSPACE_INFO, wmGD.xa_DT_WORKSPACE_INFO, 32, PropModeReplace, (unsigned char *)pWsInfo, (cInfo * sizeof(WorkspaceInfo))/sizeof(long)); } /* END OF FUNCTION SetWorkspaceInfo */ #endif /* HP_VUE */ /*************************************<->************************************* * * 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_ 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, iwin; 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 = 6; /* 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]; /* 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_ 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; Atom aProperty; /* * 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) { #ifdef PARANOID /* * Lock down the server to prevent changes to this * property while we "edit" it. */ XGrabServer(DISPLAY); #endif /* PARANOID */ /* * 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); #ifdef PARANOID /* Give the server back */ XUngrabServer(DISPLAY); #endif /* PARANOID */ /* * 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=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 */ #endif /* WSM */