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"
61 * Function Declarations:
64 #include "WmProperty.h"
71 static SizeHints sizeHints;
75 /*************************************<->*************************************
78 * GetNormalHints (pCD)
83 * This function replaces the XGetNormalHints Xlib function. This function
84 * gets the information in the WM_NORMAL_HINTS property on the client window.
85 * The property encoding can be any of the supported versions (R2, R3+).
95 * Return = A pointer to a filled out SizeHints structure is returned.
96 * Default values are set if the WM_NORMAL_HINTS property could
99 *************************************<->***********************************/
106 PropSizeHints *property = NULL;
109 unsigned long leftover;
110 unsigned long nitems;
114 * Retrieve the property data.
116 * ICCC_R2 version: nitems = PROP_SIZE_HINTS_ELEMENTS - 3
117 * ICCC_CURRENT version: nitems = PROP_SIZE_HINTS_ELEMENTS
121 if ((!HasProperty (pCD, XA_WM_NORMAL_HINTS)) ||
122 ((Success != XGetWindowProperty (DISPLAY, pCD->client,
123 XA_WM_NORMAL_HINTS, 0L, (long)PROP_SIZE_HINTS_ELEMENTS,
124 False, XA_WM_SIZE_HINTS, &actualType, &actualFormat,
125 &nitems, &leftover, (unsigned char **)&property)) ||
126 (actualType != XA_WM_SIZE_HINTS) ||
127 (nitems < (PROP_SIZE_HINTS_ELEMENTS - 3)) ||
128 (actualFormat != 32)))
130 if ((Success != XGetWindowProperty (DISPLAY, pCD->client,
131 XA_WM_NORMAL_HINTS, 0L, (long)PROP_SIZE_HINTS_ELEMENTS,
132 False, XA_WM_SIZE_HINTS, &actualType, &actualFormat,
133 &nitems, &leftover, (unsigned char **)&property)) ||
134 (actualType != XA_WM_SIZE_HINTS) ||
135 (nitems < (PROP_SIZE_HINTS_ELEMENTS - 3)) ||
136 (actualFormat != 32))
140 * Indicate no property values were retrieved:
143 sizeHints.icccVersion = ICCC_UNKNOWN;
149 * Parse the hint values out of the property data:
152 sizeHints.flags = property->flags;
153 sizeHints.x = property->x;
154 sizeHints.y = property->y;
155 sizeHints.width = property->width;
156 sizeHints.height = property->height;
157 sizeHints.min_width = property->minWidth;
158 sizeHints.min_height = property->minHeight;
159 sizeHints.max_width = property->maxWidth;
160 sizeHints.max_height = property->maxHeight;
161 sizeHints.width_inc = property->widthInc;
162 sizeHints.height_inc = property->heightInc;
163 sizeHints.min_aspect.x = (int)property->minAspectX;
164 sizeHints.min_aspect.y = (int)property->minAspectY;
165 sizeHints.max_aspect.x = (int)property->maxAspectX;
166 sizeHints.max_aspect.y = (int)property->maxAspectY;
169 if (nitems == (PROP_SIZE_HINTS_ELEMENTS - 3))
175 sizeHints.icccVersion = ICCC_R2;
180 * This is ICCC_CURRENT.
183 sizeHints.icccVersion = ICCC_CURRENT;
184 sizeHints.base_width = property->baseWidth;
185 sizeHints.base_height = property->baseHeight;
186 sizeHints.win_gravity = property->winGravity;
192 * Free the property data buffer:
197 XFree ((char *)property);
202 * Return the hints values:
208 } /* END OF FUNCTION GetNormalHints */
212 /*************************************<->*************************************
214 * ProcessWmProtocols (pCD)
219 * This function reads and processes the WM_PROTOCOLS property that is
220 * associated with a client window.
222 * ICCC_COMPLIANT check added to allow older clients to work, for now...
223 * eventually, this code should be removed.
227 * pCD = pointer to client data
232 * pCD = (clientProtocols, clientProtocolCount, protocolFlags)
234 *************************************<->***********************************/
236 void ProcessWmProtocols (ClientData *pCD)
239 Atom *property = NULL;
240 #ifndef ICCC_COMPLIANT
243 unsigned long leftover;
244 unsigned long nitems;
247 #endif /* ICCC_COMPLIANT */
251 if (pCD->clientProtocols)
253 XtFree ((char *)pCD->clientProtocols);
254 pCD->clientProtocols = NULL;
256 pCD->clientProtocolCount = 0;
257 pCD->protocolFlags = 0;
261 * Read the WM_PROTOCOLS property.
264 #ifndef ICCC_COMPLIANT
266 if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
270 rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_WM_PROTOCOLS, 0L,
271 (long)MAX_CLIENT_PROTOCOL_COUNT, False, AnyPropertyType,
272 &actualType, &actualFormat, &nitems, &leftover,
273 (unsigned char **)&property);
276 if ((rValue != Success) || (actualType == None) || (actualFormat != 32))
279 if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
283 rValue = XGetWMProtocols (DISPLAY, pCD->client,
284 (Atom **)&property, &nitems);
287 #endif /* ICCC_COMPLIANT */
290 * WM_PROTOCOLS does not exist or it is an invalid type or size.
293 pCD->clientProtocols = NULL;
297 if (!(pCD->clientProtocols = (Atom *)XtMalloc (nitems * sizeof (Atom))))
299 /* unable to allocate space */
300 Warning (((char *)GETMESSAGE(54, 1, "Insufficient memory for window management data")));
305 * Save the protocols in the client data and look for predefined
309 pCD->clientProtocolCount = nitems;
311 for (i = 0; i < nitems; i++)
313 pCD->clientProtocols[i] = property[i];
314 if (property[i] == wmGD.xa_WM_SAVE_YOURSELF)
316 pCD->protocolFlags |= PROTOCOL_WM_SAVE_YOURSELF;
318 else if (property[i] == wmGD.xa_WM_TAKE_FOCUS)
320 pCD->protocolFlags |= PROTOCOL_WM_TAKE_FOCUS;
322 else if (property[i] == wmGD.xa_WM_DELETE_WINDOW)
324 pCD->protocolFlags |= PROTOCOL_WM_DELETE_WINDOW;
326 else if (property[i] == wmGD.xa_MWM_MESSAGES)
328 pCD->protocolFlags |= PROTOCOL_MWM_MESSAGES;
337 XFree ((char *)property);
341 } /* END OF FUNCTION ProcessWmProtocols */
345 /*************************************<->*************************************
347 * ProcessMwmMessages (pCD)
352 * This function reads and processes the _MWM_MESSAGES property that is
353 * associated with a client window.
358 * pCD = pointer to client data
363 * pCD = (mwmMessagesCount, mwmMessages)
365 *************************************<->***********************************/
367 void ProcessMwmMessages (ClientData *pCD)
370 long *property = NULL;
373 unsigned long leftover;
374 unsigned long nitems;
378 if (pCD->mwmMessages)
380 XtFree ((char *)pCD->mwmMessages);
381 pCD->mwmMessages = NULL;
383 pCD->mwmMessagesCount = 0;
387 * Read the _MWM_MESSAGES property.
391 if (!HasProperty (pCD, wmGD.xa_MWM_MESSAGES))
395 rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_MESSAGES, 0L,
396 (long)MAX_MWM_MESSAGES_COUNT, False, AnyPropertyType,
397 &actualType, &actualFormat, &nitems, &leftover,
398 (unsigned char **)&property);
401 if ((rValue != Success) || (actualType == None) || (actualFormat != 32)
405 * _MWM_MESSAGES does not exist or it is an invalid type.
408 pCD->mwmMessages = NULL;
412 if (!(pCD->mwmMessages = (long *)XtMalloc (nitems * sizeof (long))))
414 /* unable to allocate space */
415 Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
420 * Save the protocols in the client data and look for predefined
424 pCD->mwmMessagesCount = nitems;
426 for (i = 0; i < nitems; i++)
428 if ((pCD->mwmMessages[i] = property[i]) == wmGD.xa_MWM_OFFSET)
430 pCD->protocolFlags |= PROTOCOL_MWM_OFFSET;
439 XFree ((char *)property);
443 } /* END OF FUNCTION ProcessMwmMessages */
447 /*************************************<->*************************************
449 * SetMwmInfo (propWindow, flags, wmWindow)
454 * This function sets up the _MOTIF_WM_INFO property on the specified (usually
460 * propWindow = window on which the _MOTIF_WM_INFO property is to be set
462 * flags = motifWmInfo.flags value
464 * wmWindow = motifWmInfo.wmWindow value
469 * _MWM_INFO = this property is set on the specified window
471 *************************************<->***********************************/
473 void SetMwmInfo (Window propWindow, long flags, Window wmWindow)
475 PropMwmInfo property;
478 property.flags = flags;
479 property.wmWindow = wmWindow;
481 XChangeProperty (DISPLAY, propWindow, wmGD.xa_MWM_INFO, wmGD.xa_MWM_INFO,
482 32, PropModeReplace, (unsigned char *)&property,
483 PROP_MWM_INFO_ELEMENTS);
485 } /* END OF FUNCTION SetMwmInfo */
489 /*************************************<->*************************************
491 * SetMwmSaveSessionInfo (wmWindow)
496 * This function sets up the WM_SAVE_YOURSELF property on the wm window
501 * wmWindow = motifWmInfo.wmWindow
506 * WM_SAVE_YOURSELF = this property is set on the wm window
508 *************************************<->***********************************/
510 void SetMwmSaveSessionInfo (Window wmWindow)
514 property = wmGD.xa_WM_SAVE_YOURSELF;
516 XChangeProperty (DISPLAY, wmWindow,
517 wmGD.xa_WM_PROTOCOLS, XA_ATOM,
519 (unsigned char *) &property, 1);
520 SetWMState(wmWindow, NORMAL_STATE, 0);
522 } /* END OF FUNCTION SetMwmSaveSessionInfo */
526 /*************************************<->*************************************
528 * GetWMState (window)
533 * This function gets the WM_STATE property on a client top-level
539 * window = client window from which the WM_STATE property is to be retrieved
544 * RETURN = a pointer to the WM_STATE property value (NULL if not defined)
549 * This function will eventually be superceded when WM_STATE support is
550 * added to the official X release.
552 *************************************<->***********************************/
559 PropWMState *property = NULL;
562 unsigned long nitems;
563 unsigned long leftover;
566 ret_val = XGetWindowProperty (DISPLAY, window, wmGD.xa_WM_STATE,
567 0L, PROP_WM_STATE_ELEMENTS,
568 False, wmGD.xa_WM_STATE,
569 &actual_type, &actual_format,
570 &nitems, &leftover, (unsigned char **)&property);
572 if (!((ret_val == Success) && (actual_type == wmGD.xa_WM_STATE) &&
573 (nitems == PROP_WM_STATE_ELEMENTS)))
576 * The property could not be retrieved or is not correctly set up.
581 XFree ((char *)property);
588 } /* END OF FUNCTION GetWMState */
592 /*************************************<->*************************************
594 * SetWMState (window, state, icon)
599 * This function sets up the WM_STATE property on a client top-level
605 * window = client window on which the WM_STATE property is to be set
607 * state = state of the client application
609 * icon = window manager's icon window
614 * WM_STATE = this property is set on the client window
619 * This function will eventually be superceded when WM_STATE support is
620 * added to the official X release.
622 *************************************<->***********************************/
624 void SetWMState (Window window, int state, Window icon)
626 PropWMState property;
629 property.state = state;
630 property.icon = icon;
632 XChangeProperty (DISPLAY, window, wmGD.xa_WM_STATE, wmGD.xa_WM_STATE, 32,
633 PropModeReplace, (unsigned char *)&property, PROP_WM_STATE_ELEMENTS);
635 } /* END OF FUNCTION SetWMState */
639 /*************************************<->*************************************
647 * This function reads any _MWM_HINTS property that is associated with a
652 * pCD = pointer to client data
656 * RETURN = ptr to mwm hints property, or NULL ptr if failure
658 *************************************<->***********************************/
666 PropMwmHints *property = NULL;
669 unsigned long nitems;
670 unsigned long leftover;
674 if (!HasProperty(pCD, wmGD.xa_MWM_HINTS))
678 ret_val = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_HINTS,
679 0L, PROP_MWM_HINTS_ELEMENTS,
680 False, wmGD.xa_MWM_HINTS,
681 &actual_type, &actual_format,
682 &nitems, &leftover, (unsigned char **)&property);
685 * Retrieve the property data.
687 * Motif 1.1.n clients: nitems = PROP_MWM_HINTS_ELEMENTS
688 * Motif 1.2 clients: nitems = PROP_MWM_HINTS_ELEMENTS + 2
690 * NOTES: We don't need to check (nitems == PROP_MWM_HINTS_ELEMENTS)
693 * If running Motif 1.1.n client with Mwm 1.2, then ignore extra elements
694 * since property.flags won't have extra elements set.
696 * If running Motif 1.2 client with Mwm 1.1.n, then ignore extra elements
697 * since Mwm 1.1.n won't try to access the extra elements.
700 if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_HINTS))
702 return (property); /* indicate success */
707 * The property could not be retrieved or is not correctly set up.
712 XFree ((char *)property);
715 return (NULL); /* indicate failure */
718 } /* END OF FUNCTION GetMwmHints */
722 /*************************************<->*************************************
725 * GetMwmInfo (rootWindowOfScreen)
730 * This function reads the _MOTIF_WM_INFO property from the root window if
735 * pSD = pointer to screen data
739 * RETURN = ptr to motif wm info property, or NULL ptr if no property
741 *************************************<->***********************************/
743 PropMwmInfo *GetMwmInfo (Window rootWindowOfScreen)
746 PropMwmInfo *property = NULL;
749 unsigned long nitems;
750 unsigned long leftover;
753 ret_val = XGetWindowProperty (DISPLAY, rootWindowOfScreen,
755 0L, PROP_MWM_INFO_ELEMENTS,
756 False, wmGD.xa_MWM_INFO,
757 &actual_type, &actual_format,
759 (unsigned char **)&property);
761 if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_INFO) &&
762 (nitems == PROP_MWM_INFO_ELEMENTS))
764 return (property); /* indicate success */
769 * The property could not be retrieved or is not correctly set up.
774 XFree ((char *)property);
777 return (NULL); /* indicate failure */
780 } /* END OF FUNCTION GetMwmInfo */
784 /*************************************<->*************************************
786 * ProcessWmColormapWindows (pCD)
791 * This function retrieves and processes the WM_COLORMAP_WINDOWS client
797 * pCD = pointer to client data
802 * pCD = (cmapWindows, clientCmapList, clientCmapCount, clientCmapIndex)
804 *************************************<->***********************************/
806 void ProcessWmColormapWindows (ClientData *pCD)
809 Window *property = NULL;
812 unsigned long leftover;
813 unsigned long nitems;
816 Colormap *pColormaps;
818 XWindowAttributes wAttributes;
820 XSetWindowAttributes sAttributes;
821 #ifndef OLD_COLORMAP /* colormaps */
827 * pCD->clientCmapCount and pCD->clientCmapIndex are initialized in
832 * Read the WM_COLORMAP_WINDOWS property.
835 rValue = XGetWindowProperty (DISPLAY, pCD->client,
836 wmGD.xa_WM_COLORMAP_WINDOWS, 0L,
837 (long)MAX_COLORMAP_WINDOWS_COUNT, False, AnyPropertyType,
838 &actualType, &actualFormat, &nitems, &leftover,
839 (unsigned char **)&property);
842 if ((rValue == Success) && (actualType != None) && (actualFormat == 32) &&
846 * WM_COLORMAP_WINDOWS exists and is a valid type.
849 if (!(pWindows = (Window *)XtMalloc ((nitems * sizeof (Window)) + 1)) ||
850 !(pColormaps = (Colormap *)XtMalloc ((nitems*sizeof(Colormap)) + 1)))
852 /* unable to allocate space */
853 Warning (((char *)GETMESSAGE(54, 3, "Insufficient memory for window management data")));
856 XtFree ((char *)pWindows);
859 #ifndef OLD_COLORMAP /* colormap */
860 /* Is the above OSF code a bug -- allocates one extra byte, rather */
861 /* than one extra element, for the top window if needed? */
862 else if ( ! (pCmapFlags = (int *)XtCalloc(nitems+1,sizeof(int)))) {
863 /* unable to allocate space */
864 Warning (((char *)GETMESSAGE(54, 4, "Insufficient memory for window manager flags")));
865 XtFree ((char *)pWindows); XtFree ((char *)pColormaps);
871 * Check to see if the top-level client window is in the list.
872 * If it is not then add it to the head of the list.
875 for (i = 0; i < nitems; i++)
877 if (property[i] == pCD->client)
886 /* add the client window to the colormap window list */
887 pWindows[0] = pCD->client;
888 pColormaps[0] = FindColormap (pCD, pCD->client);
892 sAttributes.event_mask = (ColormapChangeMask);
893 for (i = 0; i < nitems; i++)
895 if ((pColormaps[colormapCount] =
896 FindColormap (pCD, property[i])) != None)
898 pWindows[colormapCount] = property[i];
901 else if (XFindContext (DISPLAY, property[i],
902 wmGD.windowContextType, (caddr_t *)&pcd))
905 * The window is not a top level window or a window that
906 * is already being tracked for colormap changes.
907 * Track colormap attribute changes.
910 XChangeWindowAttributes (DISPLAY, property[i], CWEventMask,
914 if (XGetWindowAttributes (DISPLAY, property[i],
917 pWindows[colormapCount] = property[i];
918 pColormaps[colormapCount] = wAttributes.colormap;
925 * Free up the old colormap window data if it has been set. Set
926 * new window contexts.
929 ResetColormapData (pCD, pWindows, colormapCount);
933 * Set the colormap window data.
936 pCD->clientColormap = pColormaps[0];
937 if (colormapCount > 1)
940 * The top level window and at least one other window is in
941 * the colormap windows list.
944 pCD->clientCmapCount = colormapCount;
945 pCD->cmapWindows = pWindows;
946 pCD->clientCmapList = pColormaps;
947 pCD->clientCmapIndex = 0;
948 #ifndef OLD_COLORMAP /* colormap */
949 pCD->clientCmapFlags = pCmapFlags;
955 * Only the top level window is being tracked for colormap
959 pCD->clientCmapCount = 0;
960 XtFree ((char *)pWindows);
961 XtFree ((char *)pColormaps);
962 #ifndef OLD_COLORMAP /* colormap */
963 XtFree((char *)pCmapFlags);
972 XFree ((char *)property);
976 } /* END OF FUNCTION ProcessWmColormapWindows */
980 /*************************************<->*************************************
982 * FindColormap (pCD, window)
987 * This function checks colormap information that is currently saved in
988 * the client data for the colormap of the specified window.
993 * pCD = pointer to client data
995 * window = get the colormap id for this window
1000 * RETURN = colormap id for window (NULL if no colormap information)
1002 *************************************<->***********************************/
1004 Colormap FindColormap (ClientData *pCD, Window window)
1006 Colormap colormap = (Colormap)0;
1010 if (pCD->clientCmapCount == 0)
1013 * If the colormap count is 0 there is no list of colormaps and
1014 * clientColormap is the colormap of the top-level window.
1017 if (window == pCD->client)
1019 colormap = pCD->clientColormap;
1024 for (i = 0; i < pCD->clientCmapCount; i++)
1026 if (pCD->cmapWindows[i] == window)
1028 colormap = pCD->clientCmapList[i];
1036 } /* END OF FUNCTION FindColormap */
1040 /*************************************<->*************************************
1042 * GetMwmMenuItems (pCD)
1047 * This function reads and processes any _MWM_MENU property that is
1048 * associated with a client window and returns a list of MenuItem structures
1049 * specified by the property, or NULL.
1054 * pCD = pointer to client data
1059 * Return = MenuItem list or NULL.
1061 *************************************<->***********************************/
1068 XTextProperty textProperty;
1069 MenuItem *menuItems;
1072 * Read the _MWM_MENU property.
1075 textProperty.value = (unsigned char *)NULL;
1076 rValue = XGetTextProperty(DISPLAY, pCD->client, &textProperty,
1078 if ((rValue == 0) || (textProperty.value == (unsigned char *)NULL))
1079 /* _MWM_MENU does not exist or it is an invalid type. */
1085 /* parse the property string */
1090 if (XmbTextPropertyToTextList(DISPLAY, &textProperty,
1091 &textList, &nItems) != Success)
1097 menuItems = ParseMwmMenuStr (PSD_FOR_CLIENT(pCD),
1098 (unsigned char *)textList[0]);
1099 XFreeStringList(textList);
1102 XFree((void *)textProperty.value);
1107 } /* END OF FUNCTION GetMwmMenuItems */
1112 /*************************************<->*************************************
1114 * GetWorkspaceHints (display, window, ppWsAtoms, pCount, pbAll)
1119 * Get the contents of the WM_COMMAND property on a window
1124 * display - X display
1125 * window - window to get hints from
1126 * ppWsAtoms - pointer to a list of workspace atoms (to be returned)
1127 * pCount - ptr to a number of atoms (to be returned)
1128 * pbAll - ptr to a boolean (to be returned)
1133 * Success if suceeded, otherwise failure code.
1138 * *ppWsAtoms - list of workspace atoms
1139 * *pCount - number of atoms in *ppWsAtoms
1140 * *pbAll - True if should put in all workspaces
1145 * The caller must XtFree *ppWsAtoms when done!!!
1147 *************************************<->***********************************/
1149 Status GetWorkspaceHints (Display *display, Window window,
1150 Atom **ppWsAtoms, unsigned int *pCount,
1154 DtWorkspaceHints *pWsHints;
1157 rcode = _DtWsmGetWorkspaceHints(display, window, &pWsHints);
1158 if (rcode == Success)
1160 if (pWsHints->flags & DT_WORKSPACE_HINTS_WORKSPACES)
1163 XtMalloc (pWsHints->numWorkspaces * sizeof(Atom));
1165 pWsHints->pWorkspaces,
1166 (pWsHints->numWorkspaces * sizeof(Atom)));
1168 *pCount = pWsHints->numWorkspaces;
1177 if ((pWsHints->flags & DT_WORKSPACE_HINTS_WSFLAGS) &&
1178 (pWsHints->wsflags & DT_WORKSPACE_FLAGS_OCCUPY_ALL))
1188 _DtWsmFreeWorkspaceHints (pWsHints);
1193 } /* END OF FUNCTION GetWorkspaceHints */
1196 /*************************************<->*************************************
1198 * SetEmbeddedClientsProperty (propWindow, pEmbeddedClients,
1204 * This function writes the _DT_WORKSPACE_EMBEDDED_CLIENTS property
1209 * propWindow = window on which the property is to be written
1210 * pEmbeddedClients = pointer to data (array of window IDs)
1211 * cEmbeddedClients = number of window IDs in the array
1213 *************************************<->***********************************/
1215 void SetEmbeddedClientsProperty (Window propWindow,
1216 Window *pEmbeddedClients, unsigned long cEmbeddedClients)
1218 XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_EMBEDDED_CLIENTS,
1219 wmGD.xa_DT_EMBEDDED_CLIENTS,
1220 32, PropModeReplace, (unsigned char *)pEmbeddedClients,
1223 } /* END OF FUNCTION SetEmbeddedClientsProperty */
1227 /*************************************<->*************************************
1229 * SetWorkspaceInfo (propWindow, pWsInfo, cInfo)
1234 * This function sets up the _DT_WORKSPACE_INFO property
1239 * propWindow = window on which the _DT_WORKSPACE_INFO property is to be set
1240 * pWsInfo = pointer to workspace info data
1241 * cInfo = size of workspace info data
1244 *************************************<->***********************************/
1246 void SetWorkspaceInfo (Window propWindow, WorkspaceInfo *pWsInfo, unsigned long cInfo)
1248 XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_WORKSPACE_INFO,
1249 wmGD.xa_DT_WORKSPACE_INFO,
1250 32, PropModeReplace, (unsigned char *)pWsInfo,
1251 (cInfo * sizeof(WorkspaceInfo))/sizeof(long));
1253 } /* END OF FUNCTION SetWorkspaceInfo */
1257 /*************************************<->*************************************
1259 * SetWorkspaceListProperty (pSD)
1264 * This function sets up the _DT_WORKSPACE_LIST property
1269 * pSD = ptr to screen data
1272 *************************************<->***********************************/
1275 SetWorkspaceListProperty (WmScreenData *pSD)
1277 WmWorkspaceData *pws;
1282 XtMalloc (pSD->numWorkspaces * sizeof(Atom));
1285 for (count = 0; count < pSD->numWorkspaces; count++)
1287 pWsList[count] = pws->id;
1291 XChangeProperty (DISPLAY, pSD->wmWorkspaceWin,
1292 wmGD.xa_DT_WORKSPACE_LIST,
1294 32, PropModeReplace, (unsigned char *)pWsList,
1295 (pSD->numWorkspaces * sizeof(Atom))/sizeof(long));
1297 XtFree ((char *) pWsList);
1299 } /* END OF FUNCTION SetWorkspaceListProperty */
1302 /*************************************<->*************************************
1304 * SetCurrentWorkspaceProperty (pSD)
1309 * This function sets up the _DT_WORKSPACE_CURRENT property
1314 * pSD = ptr to screen data
1317 *************************************<->***********************************/
1320 SetCurrentWorkspaceProperty (WmScreenData *pSD)
1324 aCurrent = pSD->pActiveWS->id;
1326 XChangeProperty (DISPLAY, pSD->wmWorkspaceWin,
1327 wmGD.xa_DT_WORKSPACE_CURRENT,
1329 32, PropModeReplace, (unsigned char *)&aCurrent,
1330 (sizeof(Atom))/sizeof(long));
1332 XSync (DISPLAY, False); /* XFlush didn't work here, why? */
1334 } /* END OF FUNCTION SetCurrentWorkspaceProperty */
1337 /*************************************<->*************************************
1339 * SetWorkspaceInfoProperty (pWS)
1344 * This function sets up the _DT_WORKSPACE_INFO_<name> property
1345 * for a particular workspace
1350 * pWS = ptr to workspace data
1353 *************************************<->***********************************/
1356 SetWorkspaceInfoProperty (WmWorkspaceData *pWS)
1367 #define WIP_NUMBER_SIZE 16
1370 * Construct our property name
1372 pch = WorkspacePropertyName (pWS);
1374 aProperty = XmInternAtom (DISPLAY, pch, FALSE);
1376 XtFree ((char *) pch);
1379 * Determine the number of strings in our vector. One for each of
1383 * backdrop background
1384 * backdrop foreground
1386 * number of backdrop windows
1387 * list of backdrop windows
1389 iNumStrings = 6; /* number of fields minus backdrop window(s) */
1390 count = 1; /* number of backdrop windows */
1391 iNumStrings += count;
1393 /* allocate string vector */
1394 ppchList = (char **) XtMalloc (iNumStrings * sizeof (char *));
1395 pch = (char *) XtMalloc (iNumStrings * WIP_NUMBER_SIZE * sizeof(char));
1399 /* Convert workspace title to ascii */
1400 sTitle = (String) WmXmStringToString (pWS->title);
1401 ppchList[i++] = (char *) sTitle;
1404 ix = (i * WIP_NUMBER_SIZE);
1405 sprintf (&pch[ix], "%d", pWS->backdrop.colorSet);
1406 ppchList[i++] = &pch[ix];
1408 /* backdrop background */
1409 ix = (i * WIP_NUMBER_SIZE);
1410 sprintf (&pch[ix], "0x%lx", pWS->backdrop.background);
1411 ppchList[i++] = &pch[ix];
1413 /* backdrop foreground */
1414 ix = (i * WIP_NUMBER_SIZE);
1415 sprintf (&pch[ix], "0x%lx", pWS->backdrop.foreground);
1416 ppchList[i++] = &pch[ix];
1419 ix = (i * WIP_NUMBER_SIZE);
1420 sprintf (&pch[ix], "0x%lx", pWS->backdrop.nameAtom);
1421 ppchList[i++] = &pch[ix];
1423 /* number of backdrop windows */
1424 ix = (i * WIP_NUMBER_SIZE);
1425 if ((pWS->backdrop.window == None))
1427 strcpy (&pch[ix], "0");
1431 sprintf (&pch[ix], "%d", count);
1433 ppchList[i++] = &pch[ix];
1435 /* backdrop windows */
1437 * One or zero backdrop windows
1438 * (NULL written if zero)
1440 ix = (i * WIP_NUMBER_SIZE);
1441 sprintf (&pch[ix], "0x%lx", pWS->backdrop.window);
1442 ppchList[i++] = &pch[ix];
1445 * Write out the property
1447 status = XmbTextListToTextProperty (DISPLAY, ppchList, iNumStrings,
1448 XStdICCTextStyle, &tp);
1449 if ((status == Success) || (status > 0))
1452 * Complete or partial conversion
1454 XSetTextProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, &tp, aProperty);
1458 XtFree ((char *) ppchList);
1460 if (sTitle) XtFree ((char *)sTitle);
1462 } /* END OF FUNCTION SetWorkspaceInfoProperty */
1465 /*************************************<->*************************************
1467 * DeleteWorkspaceInfoProperty (pWS)
1472 * This function deletes a _DT_WORKSPACE_INFO_<name> property
1473 * for a particular workspace
1478 * pWS = ptr to workspace data
1481 *************************************<->***********************************/
1484 DeleteWorkspaceInfoProperty (WmWorkspaceData *pWS)
1490 * Get the atom for the workspace property.
1492 pch = WorkspacePropertyName (pWS);
1494 aProperty = XmInternAtom (DISPLAY, pch, FALSE);
1496 XtFree ((char *) pch);
1499 * Do the property deletion
1501 XDeleteProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, aProperty);
1505 } /* END OF FUNCTION DeleteWorkspaceInfoProperty */
1508 /*************************************<->*************************************
1510 * WorkspacePropertyName (pWS)
1515 * This function returns a string containing the property name for a
1521 * pWS = ptr to workspace data
1525 * string containing the workspace property name (Free with XtFree)
1528 *************************************<->***********************************/
1531 WorkspacePropertyName (WmWorkspaceData *pWS)
1539 * Construct our property name
1541 pchName = pWS->name;
1542 len = strlen(pchName) + strlen (_XA_DT_WORKSPACE_INFO) + 4;
1544 pch = (char *) XtMalloc (len);
1545 strcpy (pch, _XA_DT_WORKSPACE_INFO);
1547 strcat (pch, pchName);
1551 } /* END OF FUNCTION WorkspacePropertyName */
1554 /*************************************<->*************************************
1556 * SetWorkspacePresence (propWindow, pWsPresence, cPresence)
1561 * This function sets up the _DT_WORKSPACE_PRESENCE property
1566 * propWindow = window on which the _DT_WORKSPACE_PRESENCE property
1568 * pWsPresence = pointer to workspace presence data
1569 * cPresence = size of workspace presence data
1572 *************************************<->***********************************/
1574 void SetWorkspacePresence (Window propWindow, Atom *pWsPresence, unsigned long cPresence)
1576 XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_WORKSPACE_PRESENCE,
1577 wmGD.xa_DT_WORKSPACE_PRESENCE, 32, PropModeReplace,
1578 (unsigned char *)pWsPresence, cPresence);
1581 } /* END OF FUNCTION SetWorkspacePresence */
1586 /*************************************<->*************************************
1588 * GetDtSessionHints (pSD, sNum)
1593 * This function reads and processes _DT_SESSION_HINTS property that is
1594 * associated with the root window of each screen managed by dtwm
1604 *************************************<->***********************************/
1606 void GetDtSessionHints (WmScreenData *pSD, int sNum)
1611 char *property = NULL;
1614 unsigned long leftover;
1615 unsigned long nitems;
1620 * Read the property.
1623 rValue = XGetWindowProperty (DISPLAY, pSD->rootWindow,
1624 wmGD.xa_DT_SESSION_HINTS, 0L,
1625 (long)1000000, False, AnyPropertyType,
1626 &actualType, &actualFormat, &nitems,
1627 &leftover, (unsigned char **)&property);
1630 if ((rValue != Success) || (actualType == None) || (actualFormat != 8))
1631 /* _DT_SESSION_HINTS does not exist or it is an invalid type. */
1633 pSD->pDtSessionItems = NULL;
1638 /* parse the property string */
1640 ParseDtSessionHints (pSD, (unsigned char *)property);
1646 XFree ((char *)property);
1650 * Delete the property so we don't see it if the user
1653 #ifndef DEBUG_SESSION_HINTS
1654 XDeleteProperty (DISPLAY, pSD->rootWindow, wmGD.xa_DT_SESSION_HINTS);
1655 #endif /* DEBUG_SESSION_HINTS */
1656 } /* END OF FUNCTION GetDtSessionHints */
1661 /*************************************<->*************************************
1663 * GetDtWmRequest (pSD, pszReq, pmore)
1668 * This function returns the next request
1673 * pSD - pointer to screen data
1674 * psdReq - pointer to a char pointer
1679 * *pszReq - pointer to null terminated string containing next
1681 * *pmore - set to true if more data is left in the property
1685 * The data for pszReq is allocated in here. The caller must free up
1686 * this space using XtFree.
1689 *************************************<->***********************************/
1700 char *chRequest = NULL;
1701 static char *property = NULL;
1702 static int iNext = -1;
1706 unsigned long leftover;
1707 static unsigned long nitems = 0;
1711 * We need to read the property again if we have no data left
1712 * over from last time;
1714 if (property == NULL)
1718 * Lock down the server to prevent changes to this
1719 * property while we "edit" it.
1721 XGrabServer(DISPLAY);
1722 #endif /* PARANOID */
1725 * Read the property and delete it.
1727 rValue = XGetWindowProperty (DISPLAY, pSD->wmWorkspaceWin,
1728 wmGD.xa_DT_WM_REQUEST, 0L,
1729 (long)1000000, True, AnyPropertyType,
1730 &actualType, &actualFormat, &nitems,
1731 &leftover, (unsigned char **)&property);
1734 /* Give the server back */
1735 XUngrabServer(DISPLAY);
1736 #endif /* PARANOID */
1739 * Validate the property that we've read
1741 if ((rValue != Success) ||
1742 (actualType == None) ||
1743 (actualFormat != 8))
1745 /* The property does not exist or it is an invalid type. */
1752 /* the property is fine, set the index of the next char. */
1759 * If we've got something, then extract and return the next
1762 if (property && iNext >= 0)
1766 for (i=iNext; i<nitems; i++)
1768 if (property [i] == '\0')
1773 if (i>=nitems) i=nitems;
1775 len = i - iNext + 1 + ((property[i] == '\0') ? 0 : 1);
1777 chRequest = (char *) XtMalloc (len);
1778 if (chRequest == NULL)
1780 Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
1784 /* dequeue the request */
1785 strncpy (chRequest, &property[iNext], len);
1786 if (property[i] != '\0')
1788 chRequest[len-1]='\0';
1793 if (iNext >= nitems)
1796 * Extracted the last request, free up the storage
1797 * and reset for next time.
1799 XFree ((char *)property);
1805 *pmore = (property != NULL);
1806 *pszReq = chRequest;
1808 } /* END OF FUNCTION GetDtWmRequest */
1811 /*************************************<->*************************************
1813 * GetIntialPropertyList (ClientData *)
1818 * Get the list of initial properties on the window
1823 * pCD - pointer to client data
1828 * pCD - paInitialProperties member is updated
1833 * The caller must XFree the paIntialialProperties member!
1835 *************************************<->***********************************/
1838 GetInitialPropertyList (ClientData *pCD)
1843 paList = XListProperties (DISPLAY, pCD->client, &iProps);
1847 pCD->paInitialProperties = paList;
1848 pCD->numInitialProperties = iProps;
1852 pCD->paInitialProperties = NULL;
1853 pCD->numInitialProperties = 0;
1856 } /* END OF FUNCTION GetInitialPropertyList */
1859 /*************************************<->*************************************
1861 * DiscardIntialPropertyList (ClientData *)
1866 * Tosses out the intial property list for a client, frees data
1871 * pCD - pointer to client data
1876 * pCD - paInitialProperties member is updated
1883 *************************************<->***********************************/
1886 DiscardInitialPropertyList (ClientData *pCD)
1888 if (pCD->paInitialProperties)
1891 * Free the initial property list.
1892 * (see HasProperty() function)
1894 XFree ((char *) pCD->paInitialProperties);
1895 pCD->paInitialProperties = NULL;
1896 pCD->numInitialProperties = 0;
1898 } /* END OF FUNCTION DiscardInitialPropertyList */
1901 /*************************************<->*************************************
1903 * HasProperty (pCD, aProperty)
1908 * Returns True if this client had this property when it was mapped
1913 * pCD - pointer to client data
1914 * aProperty - atom of property to test for
1919 * Return - True if this property was on the initial list for this
1920 * client; False otherwise.
1926 *************************************<->***********************************/
1933 Boolean bFound = False;
1937 paList = pCD->paInitialProperties;
1941 count = pCD->numInitialProperties;
1942 while ((!bFound) && (count > 0))
1944 bFound = (*paList == aProperty);
1952 * The property list doesn't exist. Return
1953 * True to force a read of this property. The most likely
1954 * case is that this property was updated after the
1955 * window was managed and needs to be read.
1961 } /* END OF FUNCTION HasProperty */