2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC.
32 static char rcsid[] = "$TOG: WmProperty.c /main/7 1997/12/02 10:00:00 bill $"
36 * (c) Copyright 1987, 1988, 1989, 1990, 1993 HEWLETT-PACKARD COMPANY */
47 #include <X11/Xatom.h>
51 * include extern functions
54 #include "WmColormap.h"
56 #include "WmResParse.h"
57 #include "WmIconBox.h"
62 * Function Declarations:
65 #include "WmProperty.h"
72 static SizeHints sizeHints;
76 /*************************************<->*************************************
79 * GetNormalHints (pCD)
84 * This function replaces the XGetNormalHints Xlib function. This function
85 * gets the information in the WM_NORMAL_HINTS property on the client window.
86 * The property encoding can be any of the supported versions (R2, R3+).
96 * Return = A pointer to a filled out SizeHints structure is returned.
97 * Default values are set if the WM_NORMAL_HINTS property could
100 *************************************<->***********************************/
107 PropSizeHints *property = NULL;
110 unsigned long leftover;
111 unsigned long nitems;
115 * Retrieve the property data.
117 * ICCC_R2 version: nitems = PROP_SIZE_HINTS_ELEMENTS - 3
118 * ICCC_CURRENT version: nitems = PROP_SIZE_HINTS_ELEMENTS
122 if ((!HasProperty (pCD, XA_WM_NORMAL_HINTS)) ||
123 ((Success != XGetWindowProperty (DISPLAY, pCD->client,
124 XA_WM_NORMAL_HINTS, 0L, (long)PROP_SIZE_HINTS_ELEMENTS,
125 False, XA_WM_SIZE_HINTS, &actualType, &actualFormat,
126 &nitems, &leftover, (unsigned char **)&property)) ||
127 (actualType != XA_WM_SIZE_HINTS) ||
128 (nitems < (PROP_SIZE_HINTS_ELEMENTS - 3)) ||
129 (actualFormat != 32)))
131 if ((Success != XGetWindowProperty (DISPLAY, pCD->client,
132 XA_WM_NORMAL_HINTS, 0L, (long)PROP_SIZE_HINTS_ELEMENTS,
133 False, XA_WM_SIZE_HINTS, &actualType, &actualFormat,
134 &nitems, &leftover, (unsigned char **)&property)) ||
135 (actualType != XA_WM_SIZE_HINTS) ||
136 (nitems < (PROP_SIZE_HINTS_ELEMENTS - 3)) ||
137 (actualFormat != 32))
141 * Indicate no property values were retrieved:
144 sizeHints.icccVersion = ICCC_UNKNOWN;
150 * Parse the hint values out of the property data:
153 sizeHints.flags = property->flags;
154 sizeHints.x = property->x;
155 sizeHints.y = property->y;
156 sizeHints.width = property->width;
157 sizeHints.height = property->height;
158 sizeHints.min_width = property->minWidth;
159 sizeHints.min_height = property->minHeight;
160 sizeHints.max_width = property->maxWidth;
161 sizeHints.max_height = property->maxHeight;
162 sizeHints.width_inc = property->widthInc;
163 sizeHints.height_inc = property->heightInc;
164 sizeHints.min_aspect.x = (int)property->minAspectX;
165 sizeHints.min_aspect.y = (int)property->minAspectY;
166 sizeHints.max_aspect.x = (int)property->maxAspectX;
167 sizeHints.max_aspect.y = (int)property->maxAspectY;
170 if (nitems == (PROP_SIZE_HINTS_ELEMENTS - 3))
176 sizeHints.icccVersion = ICCC_R2;
181 * This is ICCC_CURRENT.
184 sizeHints.icccVersion = ICCC_CURRENT;
185 sizeHints.base_width = property->baseWidth;
186 sizeHints.base_height = property->baseHeight;
187 sizeHints.win_gravity = property->winGravity;
193 * Free the property data buffer:
198 XFree ((char *)property);
203 * Return the hints values:
209 } /* END OF FUNCTION GetNormalHints */
213 /*************************************<->*************************************
215 * ProcessWmProtocols (pCD)
220 * This function reads and processes the WM_PROTOCOLS property that is
221 * associated with a client window.
223 * ICCC_COMPLIANT check added to allow older clients to work, for now...
224 * eventually, this code should be removed.
228 * pCD = pointer to client data
233 * pCD = (clientProtocols, clientProtocolCount, protocolFlags)
235 *************************************<->***********************************/
237 void ProcessWmProtocols (ClientData *pCD)
240 Atom *property = NULL;
241 #ifndef ICCC_COMPLIANT
244 unsigned long leftover;
245 unsigned long nitems;
248 #endif /* ICCC_COMPLIANT */
252 if (pCD->clientProtocols)
254 XtFree ((char *)pCD->clientProtocols);
255 pCD->clientProtocols = NULL;
257 pCD->clientProtocolCount = 0;
258 pCD->protocolFlags = 0;
262 * Read the WM_PROTOCOLS property.
265 #ifndef ICCC_COMPLIANT
267 if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
271 rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_WM_PROTOCOLS, 0L,
272 (long)MAX_CLIENT_PROTOCOL_COUNT, False, AnyPropertyType,
273 &actualType, &actualFormat, &nitems, &leftover,
274 (unsigned char **)&property);
277 if ((rValue != Success) || (actualType == None) || (actualFormat != 32))
280 if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
284 rValue = XGetWMProtocols (DISPLAY, pCD->client,
285 (Atom **)&property, &nitems);
288 #endif /* ICCC_COMPLIANT */
291 * WM_PROTOCOLS does not exist or it is an invalid type or size.
294 pCD->clientProtocols = NULL;
298 if (!(pCD->clientProtocols = (Atom *)XtMalloc (nitems * sizeof (Atom))))
300 /* unable to allocate space */
301 Warning (((char *)GETMESSAGE(54, 1, "Insufficient memory for window management data")));
306 * Save the protocols in the client data and look for predefined
310 pCD->clientProtocolCount = nitems;
312 for (i = 0; i < nitems; i++)
314 pCD->clientProtocols[i] = property[i];
315 if (property[i] == wmGD.xa_WM_SAVE_YOURSELF)
317 pCD->protocolFlags |= PROTOCOL_WM_SAVE_YOURSELF;
319 else if (property[i] == wmGD.xa_WM_TAKE_FOCUS)
321 pCD->protocolFlags |= PROTOCOL_WM_TAKE_FOCUS;
323 else if (property[i] == wmGD.xa_WM_DELETE_WINDOW)
325 pCD->protocolFlags |= PROTOCOL_WM_DELETE_WINDOW;
327 else if (property[i] == wmGD.xa_MWM_MESSAGES)
329 pCD->protocolFlags |= PROTOCOL_MWM_MESSAGES;
338 XFree ((char *)property);
342 } /* END OF FUNCTION ProcessWmProtocols */
346 /*************************************<->*************************************
348 * ProcessMwmMessages (pCD)
353 * This function reads and processes the _MWM_MESSAGES property that is
354 * associated with a client window.
359 * pCD = pointer to client data
364 * pCD = (mwmMessagesCount, mwmMessages)
366 *************************************<->***********************************/
368 void ProcessMwmMessages (ClientData *pCD)
371 long *property = NULL;
374 unsigned long leftover;
375 unsigned long nitems;
379 if (pCD->mwmMessages)
381 XtFree ((char *)pCD->mwmMessages);
382 pCD->mwmMessages = NULL;
384 pCD->mwmMessagesCount = 0;
388 * Read the _MWM_MESSAGES property.
392 if (!HasProperty (pCD, wmGD.xa_MWM_MESSAGES))
396 rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_MESSAGES, 0L,
397 (long)MAX_MWM_MESSAGES_COUNT, False, AnyPropertyType,
398 &actualType, &actualFormat, &nitems, &leftover,
399 (unsigned char **)&property);
402 if ((rValue != Success) || (actualType == None) || (actualFormat != 32)
406 * _MWM_MESSAGES does not exist or it is an invalid type.
409 pCD->mwmMessages = NULL;
413 if (!(pCD->mwmMessages = (long *)XtMalloc (nitems * sizeof (long))))
415 /* unable to allocate space */
416 Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
421 * Save the protocols in the client data and look for predefined
425 pCD->mwmMessagesCount = nitems;
427 for (i = 0; i < nitems; i++)
429 if ((pCD->mwmMessages[i] = property[i]) == wmGD.xa_MWM_OFFSET)
431 pCD->protocolFlags |= PROTOCOL_MWM_OFFSET;
440 XFree ((char *)property);
444 } /* END OF FUNCTION ProcessMwmMessages */
448 /*************************************<->*************************************
450 * SetMwmInfo (propWindow, flags, wmWindow)
455 * This function sets up the _MOTIF_WM_INFO property on the specified (usually
461 * propWindow = window on which the _MOTIF_WM_INFO property is to be set
463 * flags = motifWmInfo.flags value
465 * wmWindow = motifWmInfo.wmWindow value
470 * _MWM_INFO = this property is set on the specified window
472 *************************************<->***********************************/
474 void SetMwmInfo (Window propWindow, long flags, Window wmWindow)
476 PropMwmInfo property;
479 property.flags = flags;
480 property.wmWindow = wmWindow;
482 XChangeProperty (DISPLAY, propWindow, wmGD.xa_MWM_INFO, wmGD.xa_MWM_INFO,
483 32, PropModeReplace, (unsigned char *)&property,
484 PROP_MWM_INFO_ELEMENTS);
486 } /* END OF FUNCTION SetMwmInfo */
490 /*************************************<->*************************************
492 * SetMwmSaveSessionInfo (wmWindow)
497 * This function sets up the WM_SAVE_YOURSELF property on the wm window
502 * wmWindow = motifWmInfo.wmWindow
507 * WM_SAVE_YOURSELF = this property is set on the wm window
509 *************************************<->***********************************/
511 void SetMwmSaveSessionInfo (Window wmWindow)
515 property = wmGD.xa_WM_SAVE_YOURSELF;
517 XChangeProperty (DISPLAY, wmWindow,
518 wmGD.xa_WM_PROTOCOLS, XA_ATOM,
520 (unsigned char *) &property, 1);
521 SetWMState(wmWindow, NORMAL_STATE, 0);
523 } /* END OF FUNCTION SetMwmSaveSessionInfo */
527 /*************************************<->*************************************
529 * GetWMState (window)
534 * This function gets the WM_STATE property on a client top-level
540 * window = client window from which the WM_STATE property is to be retrieved
545 * RETURN = a pointer to the WM_STATE property value (NULL if not defined)
550 * This function will eventually be superceded when WM_STATE support is
551 * added to the official X release.
553 *************************************<->***********************************/
560 PropWMState *property = NULL;
563 unsigned long nitems;
564 unsigned long leftover;
567 ret_val = XGetWindowProperty (DISPLAY, window, wmGD.xa_WM_STATE,
568 0L, PROP_WM_STATE_ELEMENTS,
569 False, wmGD.xa_WM_STATE,
570 &actual_type, &actual_format,
571 &nitems, &leftover, (unsigned char **)&property);
573 if (!((ret_val == Success) && (actual_type == wmGD.xa_WM_STATE) &&
574 (nitems == PROP_WM_STATE_ELEMENTS)))
577 * The property could not be retrieved or is not correctly set up.
582 XFree ((char *)property);
589 } /* END OF FUNCTION GetWMState */
593 /*************************************<->*************************************
595 * SetWMState (window, state, icon)
600 * This function sets up the WM_STATE property on a client top-level
606 * window = client window on which the WM_STATE property is to be set
608 * state = state of the client application
610 * icon = window manager's icon window
615 * WM_STATE = this property is set on the client window
620 * This function will eventually be superceded when WM_STATE support is
621 * added to the official X release.
623 *************************************<->***********************************/
625 void SetWMState (Window window, int state, Window icon)
627 PropWMState property;
630 property.state = state;
631 property.icon = icon;
633 XChangeProperty (DISPLAY, window, wmGD.xa_WM_STATE, wmGD.xa_WM_STATE, 32,
634 PropModeReplace, (unsigned char *)&property, PROP_WM_STATE_ELEMENTS);
636 } /* END OF FUNCTION SetWMState */
640 /*************************************<->*************************************
648 * This function reads any _MWM_HINTS property that is associated with a
653 * pCD = pointer to client data
657 * RETURN = ptr to mwm hints property, or NULL ptr if failure
659 *************************************<->***********************************/
667 PropMwmHints *property = NULL;
670 unsigned long nitems;
671 unsigned long leftover;
675 if (!HasProperty(pCD, wmGD.xa_MWM_HINTS))
679 ret_val = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_HINTS,
680 0L, PROP_MWM_HINTS_ELEMENTS,
681 False, wmGD.xa_MWM_HINTS,
682 &actual_type, &actual_format,
683 &nitems, &leftover, (unsigned char **)&property);
686 * Retrieve the property data.
688 * Motif 1.1.n clients: nitems = PROP_MWM_HINTS_ELEMENTS
689 * Motif 1.2 clients: nitems = PROP_MWM_HINTS_ELEMENTS + 2
691 * NOTES: We don't need to check (nitems == PROP_MWM_HINTS_ELEMENTS)
694 * If running Motif 1.1.n client with Mwm 1.2, then ignore extra elements
695 * since property.flags won't have extra elements set.
697 * If running Motif 1.2 client with Mwm 1.1.n, then ignore extra elements
698 * since Mwm 1.1.n won't try to access the extra elements.
701 if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_HINTS))
703 return (property); /* indicate success */
708 * The property could not be retrieved or is not correctly set up.
713 XFree ((char *)property);
716 return (NULL); /* indicate failure */
719 } /* END OF FUNCTION GetMwmHints */
723 /*************************************<->*************************************
726 * GetMwmInfo (rootWindowOfScreen)
731 * This function reads the _MOTIF_WM_INFO property from the root window if
736 * pSD = pointer to screen data
740 * RETURN = ptr to motif wm info property, or NULL ptr if no property
742 *************************************<->***********************************/
744 PropMwmInfo *GetMwmInfo (Window rootWindowOfScreen)
747 PropMwmInfo *property = NULL;
750 unsigned long nitems;
751 unsigned long leftover;
754 ret_val = XGetWindowProperty (DISPLAY, rootWindowOfScreen,
756 0L, PROP_MWM_INFO_ELEMENTS,
757 False, wmGD.xa_MWM_INFO,
758 &actual_type, &actual_format,
760 (unsigned char **)&property);
762 if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_INFO) &&
763 (nitems == PROP_MWM_INFO_ELEMENTS))
765 return (property); /* indicate success */
770 * The property could not be retrieved or is not correctly set up.
775 XFree ((char *)property);
778 return (NULL); /* indicate failure */
781 } /* END OF FUNCTION GetMwmInfo */
785 /*************************************<->*************************************
787 * ProcessWmColormapWindows (pCD)
792 * This function retrieves and processes the WM_COLORMAP_WINDOWS client
798 * pCD = pointer to client data
803 * pCD = (cmapWindows, clientCmapList, clientCmapCount, clientCmapIndex)
805 *************************************<->***********************************/
807 void ProcessWmColormapWindows (ClientData *pCD)
810 Window *property = NULL;
813 unsigned long leftover;
814 unsigned long nitems;
817 Colormap *pColormaps;
819 XWindowAttributes wAttributes;
821 XSetWindowAttributes sAttributes;
822 #ifndef OLD_COLORMAP /* colormaps */
828 * pCD->clientCmapCount and pCD->clientCmapIndex are initialized in
833 * Read the WM_COLORMAP_WINDOWS property.
836 rValue = XGetWindowProperty (DISPLAY, pCD->client,
837 wmGD.xa_WM_COLORMAP_WINDOWS, 0L,
838 (long)MAX_COLORMAP_WINDOWS_COUNT, False, AnyPropertyType,
839 &actualType, &actualFormat, &nitems, &leftover,
840 (unsigned char **)&property);
843 if ((rValue == Success) && (actualType != None) && (actualFormat == 32) &&
847 * WM_COLORMAP_WINDOWS exists and is a valid type.
850 if (!(pWindows = (Window *)XtMalloc ((nitems * sizeof (Window)) + 1)) ||
851 !(pColormaps = (Colormap *)XtMalloc ((nitems*sizeof(Colormap)) + 1)))
853 /* unable to allocate space */
854 Warning (((char *)GETMESSAGE(54, 3, "Insufficient memory for window management data")));
857 XtFree ((char *)pWindows);
860 #ifndef OLD_COLORMAP /* colormap */
861 /* Is the above OSF code a bug -- allocates one extra byte, rather */
862 /* than one extra element, for the top window if needed? */
863 else if ( ! (pCmapFlags = (int *)XtCalloc(nitems+1,sizeof(int)))) {
864 /* unable to allocate space */
865 Warning (((char *)GETMESSAGE(54, 4, "Insufficient memory for window manager flags")));
866 XtFree ((char *)pWindows); XtFree ((char *)pColormaps);
872 * Check to see if the top-level client window is in the list.
873 * If it is not then add it to the head of the list.
876 for (i = 0; i < nitems; i++)
878 if (property[i] == pCD->client)
887 /* add the client window to the colormap window list */
888 pWindows[0] = pCD->client;
889 pColormaps[0] = FindColormap (pCD, pCD->client);
893 sAttributes.event_mask = (ColormapChangeMask);
894 for (i = 0; i < nitems; i++)
896 if ((pColormaps[colormapCount] =
897 FindColormap (pCD, property[i])) != None)
899 pWindows[colormapCount] = property[i];
902 else if (XFindContext (DISPLAY, property[i],
903 wmGD.windowContextType, (caddr_t *)&pcd))
906 * The window is not a top level window or a window that
907 * is already being tracked for colormap changes.
908 * Track colormap attribute changes.
911 XChangeWindowAttributes (DISPLAY, property[i], CWEventMask,
915 if (XGetWindowAttributes (DISPLAY, property[i],
918 pWindows[colormapCount] = property[i];
919 pColormaps[colormapCount] = wAttributes.colormap;
926 * Free up the old colormap window data if it has been set. Set
927 * new window contexts.
930 ResetColormapData (pCD, pWindows, colormapCount);
934 * Set the colormap window data.
937 pCD->clientColormap = pColormaps[0];
938 if (colormapCount > 1)
941 * The top level window and at least one other window is in
942 * the colormap windows list.
945 pCD->clientCmapCount = colormapCount;
946 pCD->cmapWindows = pWindows;
947 pCD->clientCmapList = pColormaps;
948 pCD->clientCmapIndex = 0;
949 #ifndef OLD_COLORMAP /* colormap */
950 pCD->clientCmapFlags = pCmapFlags;
956 * Only the top level window is being tracked for colormap
960 pCD->clientCmapCount = 0;
961 XtFree ((char *)pWindows);
962 XtFree ((char *)pColormaps);
963 #ifndef OLD_COLORMAP /* colormap */
964 XtFree((char *)pCmapFlags);
973 XFree ((char *)property);
977 } /* END OF FUNCTION ProcessWmColormapWindows */
981 /*************************************<->*************************************
983 * FindColormap (pCD, window)
988 * This function checks colormap information that is currently saved in
989 * the client data for the colormap of the specified window.
994 * pCD = pointer to client data
996 * window = get the colormap id for this window
1001 * RETURN = colormap id for window (NULL if no colormap information)
1003 *************************************<->***********************************/
1005 Colormap FindColormap (ClientData *pCD, Window window)
1007 Colormap colormap = (Colormap)0;
1011 if (pCD->clientCmapCount == 0)
1014 * If the colormap count is 0 there is no list of colormaps and
1015 * clientColormap is the colormap of the top-level window.
1018 if (window == pCD->client)
1020 colormap = pCD->clientColormap;
1025 for (i = 0; i < pCD->clientCmapCount; i++)
1027 if (pCD->cmapWindows[i] == window)
1029 colormap = pCD->clientCmapList[i];
1037 } /* END OF FUNCTION FindColormap */
1041 /*************************************<->*************************************
1043 * GetMwmMenuItems (pCD)
1048 * This function reads and processes any _MWM_MENU property that is
1049 * associated with a client window and returns a list of MenuItem structures
1050 * specified by the property, or NULL.
1055 * pCD = pointer to client data
1060 * Return = MenuItem list or NULL.
1062 *************************************<->***********************************/
1069 XTextProperty textProperty;
1070 MenuItem *menuItems;
1073 * Read the _MWM_MENU property.
1076 textProperty.value = (unsigned char *)NULL;
1077 rValue = XGetTextProperty(DISPLAY, pCD->client, &textProperty,
1079 if ((rValue == 0) || (textProperty.value == (unsigned char *)NULL))
1080 /* _MWM_MENU does not exist or it is an invalid type. */
1086 /* parse the property string */
1091 if (XmbTextPropertyToTextList(DISPLAY, &textProperty,
1092 &textList, &nItems) != Success)
1098 menuItems = ParseMwmMenuStr (PSD_FOR_CLIENT(pCD),
1099 (unsigned char *)textList[0]);
1100 XFreeStringList(textList);
1103 XFree((void *)textProperty.value);
1108 } /* END OF FUNCTION GetMwmMenuItems */
1113 /*************************************<->*************************************
1115 * GetWorkspaceHints (display, window, ppWsAtoms, pCount, pbAll)
1120 * Get the contents of the WM_COMMAND property on a window
1125 * display - X display
1126 * window - window to get hints from
1127 * ppWsAtoms - pointer to a list of workspace atoms (to be returned)
1128 * pCount - ptr to a number of atoms (to be returned)
1129 * pbAll - ptr to a boolean (to be returned)
1134 * Success if suceeded, otherwise failure code.
1139 * *ppWsAtoms - list of workspace atoms
1140 * *pCount - number of atoms in *ppWsAtoms
1141 * *pbAll - True if should put in all workspaces
1146 * The caller must XtFree *ppWsAtoms when done!!!
1148 *************************************<->***********************************/
1150 Status GetWorkspaceHints (Display *display, Window window,
1151 Atom **ppWsAtoms, unsigned int *pCount,
1155 DtWorkspaceHints *pWsHints;
1158 rcode = _DtWsmGetWorkspaceHints(display, window, &pWsHints);
1159 if (rcode == Success)
1161 if (pWsHints->flags & DT_WORKSPACE_HINTS_WORKSPACES)
1164 XtMalloc (pWsHints->numWorkspaces * sizeof(Atom));
1166 pWsHints->pWorkspaces,
1167 (pWsHints->numWorkspaces * sizeof(Atom)));
1169 *pCount = pWsHints->numWorkspaces;
1178 if ((pWsHints->flags & DT_WORKSPACE_HINTS_WSFLAGS) &&
1179 (pWsHints->wsflags & DT_WORKSPACE_FLAGS_OCCUPY_ALL))
1189 _DtWsmFreeWorkspaceHints (pWsHints);
1194 } /* END OF FUNCTION GetWorkspaceHints */
1197 /*************************************<->*************************************
1199 * SetEmbeddedClientsProperty (propWindow, pEmbeddedClients,
1205 * This function writes the _DT_WORKSPACE_EMBEDDED_CLIENTS property
1210 * propWindow = window on which the property is to be written
1211 * pEmbeddedClients = pointer to data (array of window IDs)
1212 * cEmbeddedClients = number of window IDs in the array
1214 *************************************<->***********************************/
1216 void SetEmbeddedClientsProperty (Window propWindow,
1217 Window *pEmbeddedClients, unsigned long cEmbeddedClients)
1219 XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_EMBEDDED_CLIENTS,
1220 wmGD.xa_DT_EMBEDDED_CLIENTS,
1221 32, PropModeReplace, (unsigned char *)pEmbeddedClients,
1224 } /* END OF FUNCTION SetEmbeddedClientsProperty */
1228 /*************************************<->*************************************
1230 * SetWorkspaceInfo (propWindow, pWsInfo, cInfo)
1235 * This function sets up the _DT_WORKSPACE_INFO property
1240 * propWindow = window on which the _DT_WORKSPACE_INFO property is to be set
1241 * pWsInfo = pointer to workspace info data
1242 * cInfo = size of workspace info data
1245 *************************************<->***********************************/
1247 void SetWorkspaceInfo (Window propWindow, WorkspaceInfo *pWsInfo, unsigned long cInfo)
1249 XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_WORKSPACE_INFO,
1250 wmGD.xa_DT_WORKSPACE_INFO,
1251 32, PropModeReplace, (unsigned char *)pWsInfo,
1252 (cInfo * sizeof(WorkspaceInfo))/sizeof(long));
1254 } /* END OF FUNCTION SetWorkspaceInfo */
1258 /*************************************<->*************************************
1260 * SetWorkspaceListProperty (pSD)
1265 * This function sets up the _DT_WORKSPACE_LIST property
1270 * pSD = ptr to screen data
1273 *************************************<->***********************************/
1276 SetWorkspaceListProperty (WmScreenData *pSD)
1278 WmWorkspaceData *pws;
1283 XtMalloc (pSD->numWorkspaces * sizeof(Atom));
1286 for (count = 0; count < pSD->numWorkspaces; count++)
1288 pWsList[count] = pws->id;
1292 XChangeProperty (DISPLAY, pSD->wmWorkspaceWin,
1293 wmGD.xa_DT_WORKSPACE_LIST,
1295 32, PropModeReplace, (unsigned char *)pWsList,
1296 (pSD->numWorkspaces * sizeof(Atom))/sizeof(long));
1298 XtFree ((char *) pWsList);
1300 } /* END OF FUNCTION SetWorkspaceListProperty */
1303 /*************************************<->*************************************
1305 * SetCurrentWorkspaceProperty (pSD)
1310 * This function sets up the _DT_WORKSPACE_CURRENT property
1315 * pSD = ptr to screen data
1318 *************************************<->***********************************/
1321 SetCurrentWorkspaceProperty (WmScreenData *pSD)
1325 aCurrent = pSD->pActiveWS->id;
1327 XChangeProperty (DISPLAY, pSD->wmWorkspaceWin,
1328 wmGD.xa_DT_WORKSPACE_CURRENT,
1330 32, PropModeReplace, (unsigned char *)&aCurrent,
1331 (sizeof(Atom))/sizeof(long));
1333 XSync (DISPLAY, False); /* XFlush didn't work here, why? */
1335 } /* END OF FUNCTION SetCurrentWorkspaceProperty */
1338 /*************************************<->*************************************
1340 * SetWorkspaceInfoProperty (pWS)
1345 * This function sets up the _DT_WORKSPACE_INFO_<name> property
1346 * for a particular workspace
1351 * pWS = ptr to workspace data
1354 *************************************<->***********************************/
1357 SetWorkspaceInfoProperty (WmWorkspaceData *pWS)
1368 #define WIP_NUMBER_SIZE 16
1371 * Construct our property name
1373 pch = WorkspacePropertyName (pWS);
1375 aProperty = XmInternAtom (DISPLAY, pch, FALSE);
1377 XtFree ((char *) pch);
1380 * Determine the number of strings in our vector. One for each of
1384 * backdrop background
1385 * backdrop foreground
1387 * number of backdrop windows
1388 * list of backdrop windows
1390 iNumStrings = 6; /* number of fields minus backdrop window(s) */
1391 count = 1; /* number of backdrop windows */
1392 iNumStrings += count;
1394 /* allocate string vector */
1395 ppchList = (char **) XtMalloc (iNumStrings * sizeof (char *));
1396 pch = (char *) XtMalloc (iNumStrings * WIP_NUMBER_SIZE * sizeof(char));
1400 /* Convert workspace title to ascii */
1401 sTitle = (String) WmXmStringToString (pWS->title);
1402 ppchList[i++] = (char *) sTitle;
1405 ix = (i * WIP_NUMBER_SIZE);
1406 sprintf (&pch[ix], "%d", pWS->backdrop.colorSet);
1407 ppchList[i++] = &pch[ix];
1409 /* backdrop background */
1410 ix = (i * WIP_NUMBER_SIZE);
1411 sprintf (&pch[ix], "0x%lx", pWS->backdrop.background);
1412 ppchList[i++] = &pch[ix];
1414 /* backdrop foreground */
1415 ix = (i * WIP_NUMBER_SIZE);
1416 sprintf (&pch[ix], "0x%lx", pWS->backdrop.foreground);
1417 ppchList[i++] = &pch[ix];
1420 ix = (i * WIP_NUMBER_SIZE);
1421 sprintf (&pch[ix], "0x%lx", pWS->backdrop.nameAtom);
1422 ppchList[i++] = &pch[ix];
1424 /* number of backdrop windows */
1425 ix = (i * WIP_NUMBER_SIZE);
1426 if ((pWS->backdrop.window == None))
1428 strcpy (&pch[ix], "0");
1432 sprintf (&pch[ix], "%d", count);
1434 ppchList[i++] = &pch[ix];
1436 /* backdrop windows */
1438 * One or zero backdrop windows
1439 * (NULL written if zero)
1441 ix = (i * WIP_NUMBER_SIZE);
1442 sprintf (&pch[ix], "0x%lx", pWS->backdrop.window);
1443 ppchList[i++] = &pch[ix];
1446 * Write out the property
1448 status = XmbTextListToTextProperty (DISPLAY, ppchList, iNumStrings,
1449 XStdICCTextStyle, &tp);
1450 if ((status == Success) || (status > 0))
1453 * Complete or partial conversion
1455 XSetTextProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, &tp, aProperty);
1459 XtFree ((char *) ppchList);
1461 if (sTitle) XtFree ((char *)sTitle);
1463 } /* END OF FUNCTION SetWorkspaceInfoProperty */
1466 /*************************************<->*************************************
1468 * DeleteWorkspaceInfoProperty (pWS)
1473 * This function deletes a _DT_WORKSPACE_INFO_<name> property
1474 * for a particular workspace
1479 * pWS = ptr to workspace data
1482 *************************************<->***********************************/
1485 DeleteWorkspaceInfoProperty (WmWorkspaceData *pWS)
1491 * Get the atom for the workspace property.
1493 pch = WorkspacePropertyName (pWS);
1495 aProperty = XmInternAtom (DISPLAY, pch, FALSE);
1497 XtFree ((char *) pch);
1500 * Do the property deletion
1502 XDeleteProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, aProperty);
1506 } /* END OF FUNCTION DeleteWorkspaceInfoProperty */
1509 /*************************************<->*************************************
1511 * WorkspacePropertyName (pWS)
1516 * This function returns a string containing the property name for a
1522 * pWS = ptr to workspace data
1526 * string containing the workspace property name (Free with XtFree)
1529 *************************************<->***********************************/
1532 WorkspacePropertyName (WmWorkspaceData *pWS)
1540 * Construct our property name
1542 pchName = pWS->name;
1543 len = strlen(pchName) + strlen (_XA_DT_WORKSPACE_INFO) + 4;
1545 pch = (char *) XtMalloc (len);
1546 strcpy (pch, _XA_DT_WORKSPACE_INFO);
1548 strcat (pch, pchName);
1552 } /* END OF FUNCTION WorkspacePropertyName */
1555 /*************************************<->*************************************
1557 * SetWorkspacePresence (propWindow, pWsPresence, cPresence)
1562 * This function sets up the _DT_WORKSPACE_PRESENCE property
1567 * propWindow = window on which the _DT_WORKSPACE_PRESENCE property
1569 * pWsPresence = pointer to workspace presence data
1570 * cPresence = size of workspace presence data
1573 *************************************<->***********************************/
1575 void SetWorkspacePresence (Window propWindow, Atom *pWsPresence, unsigned long cPresence)
1577 XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_WORKSPACE_PRESENCE,
1578 wmGD.xa_DT_WORKSPACE_PRESENCE, 32, PropModeReplace,
1579 (unsigned char *)pWsPresence, cPresence);
1582 } /* END OF FUNCTION SetWorkspacePresence */
1587 /*************************************<->*************************************
1589 * GetDtSessionHints (pSD, sNum)
1594 * This function reads and processes _DT_SESSION_HINTS property that is
1595 * associated with the root window of each screen managed by dtwm
1605 *************************************<->***********************************/
1607 void GetDtSessionHints (WmScreenData *pSD, int sNum)
1612 char *property = NULL;
1615 unsigned long leftover;
1616 unsigned long nitems;
1621 * Read the property.
1624 rValue = XGetWindowProperty (DISPLAY, pSD->rootWindow,
1625 wmGD.xa_DT_SESSION_HINTS, 0L,
1626 (long)1000000, False, AnyPropertyType,
1627 &actualType, &actualFormat, &nitems,
1628 &leftover, (unsigned char **)&property);
1631 if ((rValue != Success) || (actualType == None) || (actualFormat != 8))
1632 /* _DT_SESSION_HINTS does not exist or it is an invalid type. */
1634 pSD->pDtSessionItems = NULL;
1639 /* parse the property string */
1641 ParseDtSessionHints (pSD, (unsigned char *)property);
1647 XFree ((char *)property);
1651 * Delete the property so we don't see it if the user
1654 #ifndef DEBUG_SESSION_HINTS
1655 XDeleteProperty (DISPLAY, pSD->rootWindow, wmGD.xa_DT_SESSION_HINTS);
1656 #endif /* DEBUG_SESSION_HINTS */
1657 } /* END OF FUNCTION GetDtSessionHints */
1662 /*************************************<->*************************************
1664 * GetDtWmRequest (pSD, pszReq, pmore)
1669 * This function returns the next request
1674 * pSD - pointer to screen data
1675 * psdReq - pointer to a char pointer
1680 * *pszReq - pointer to null terminated string containing next
1682 * *pmore - set to true if more data is left in the property
1686 * The data for pszReq is allocated in here. The caller must free up
1687 * this space using XtFree.
1690 *************************************<->***********************************/
1701 char *chRequest = NULL;
1702 static char *property = NULL;
1703 static int iNext = -1;
1707 unsigned long leftover;
1708 static unsigned long nitems = 0;
1712 * We need to read the property again if we have no data left
1713 * over from last time;
1715 if (property == NULL)
1719 * Lock down the server to prevent changes to this
1720 * property while we "edit" it.
1722 XGrabServer(DISPLAY);
1723 #endif /* PARANOID */
1726 * Read the property and delete it.
1728 rValue = XGetWindowProperty (DISPLAY, pSD->wmWorkspaceWin,
1729 wmGD.xa_DT_WM_REQUEST, 0L,
1730 (long)1000000, True, AnyPropertyType,
1731 &actualType, &actualFormat, &nitems,
1732 &leftover, (unsigned char **)&property);
1735 /* Give the server back */
1736 XUngrabServer(DISPLAY);
1737 #endif /* PARANOID */
1740 * Validate the property that we've read
1742 if ((rValue != Success) ||
1743 (actualType == None) ||
1744 (actualFormat != 8))
1746 /* The property does not exist or it is an invalid type. */
1753 /* the property is fine, set the index of the next char. */
1760 * If we've got something, then extract and return the next
1763 if (property && iNext >= 0)
1767 for (i=iNext; i<nitems; i++)
1769 if (property [i] == '\0')
1774 if (i>=nitems) i=nitems;
1776 len = i - iNext + 1 + ((property[i] == '\0') ? 0 : 1);
1778 chRequest = (char *) XtMalloc (len);
1779 if (chRequest == NULL)
1781 Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
1785 /* dequeue the request */
1786 strncpy (chRequest, &property[iNext], len);
1787 if (property[i] != '\0')
1789 chRequest[len-1]='\0';
1794 if (iNext >= nitems)
1797 * Extracted the last request, free up the storage
1798 * and reset for next time.
1800 XFree ((char *)property);
1806 *pmore = (property != NULL);
1807 *pszReq = chRequest;
1809 } /* END OF FUNCTION GetDtWmRequest */
1812 /*************************************<->*************************************
1814 * GetIntialPropertyList (ClientData *)
1819 * Get the list of initial properties on the window
1824 * pCD - pointer to client data
1829 * pCD - paInitialProperties member is updated
1834 * The caller must XFree the paIntialialProperties member!
1836 *************************************<->***********************************/
1839 GetInitialPropertyList (ClientData *pCD)
1844 paList = XListProperties (DISPLAY, pCD->client, &iProps);
1848 pCD->paInitialProperties = paList;
1849 pCD->numInitialProperties = iProps;
1853 pCD->paInitialProperties = NULL;
1854 pCD->numInitialProperties = 0;
1857 } /* END OF FUNCTION GetInitialPropertyList */
1860 /*************************************<->*************************************
1862 * DiscardIntialPropertyList (ClientData *)
1867 * Tosses out the intial property list for a client, frees data
1872 * pCD - pointer to client data
1877 * pCD - paInitialProperties member is updated
1884 *************************************<->***********************************/
1887 DiscardInitialPropertyList (ClientData *pCD)
1889 if (pCD->paInitialProperties)
1892 * Free the initial property list.
1893 * (see HasProperty() function)
1895 XFree ((char *) pCD->paInitialProperties);
1896 pCD->paInitialProperties = NULL;
1897 pCD->numInitialProperties = 0;
1899 } /* END OF FUNCTION DiscardInitialPropertyList */
1902 /*************************************<->*************************************
1904 * HasProperty (pCD, aProperty)
1909 * Returns True if this client had this property when it was mapped
1914 * pCD - pointer to client data
1915 * aProperty - atom of property to test for
1920 * Return - True if this property was on the initial list for this
1921 * client; False otherwise.
1927 *************************************<->***********************************/
1934 Boolean bFound = False;
1938 paList = pCD->paInitialProperties;
1942 count = pCD->numInitialProperties;
1943 while ((!bFound) && (count > 0))
1945 bFound = (*paList == aProperty);
1953 * The property list doesn't exist. Return
1954 * True to force a read of this property. The most likely
1955 * case is that this property was updated after the
1956 * window was managed and needs to be read.
1962 } /* END OF FUNCTION HasProperty */