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 libraries 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.
31 * (c) Copyright 1987, 1988, 1989, 1990, 1993 HEWLETT-PACKARD COMPANY */
41 #include <X11/Xatom.h>
42 #include <Xm/AtomMgr.h>
45 * include extern functions
48 #include "WmColormap.h"
50 #include "WmResParse.h"
51 #include "WmIconBox.h"
56 * Function Declarations:
59 #include "WmProperty.h"
66 static SizeHints sizeHints;
70 /*************************************<->*************************************
73 * GetNormalHints (pCD)
78 * This function replaces the XGetNormalHints Xlib function. This function
79 * gets the information in the WM_NORMAL_HINTS property on the client window.
80 * The property encoding can be any of the supported versions (R2, R3+).
90 * Return = A pointer to a filled out SizeHints structure is returned.
91 * Default values are set if the WM_NORMAL_HINTS property could
94 *************************************<->***********************************/
101 PropSizeHints *property = NULL;
104 unsigned long leftover;
105 unsigned long nitems;
109 * Retrieve the property data.
111 * ICCC_R2 version: nitems = PROP_SIZE_HINTS_ELEMENTS - 3
112 * ICCC_CURRENT version: nitems = PROP_SIZE_HINTS_ELEMENTS
115 if ((!HasProperty (pCD, XA_WM_NORMAL_HINTS)) ||
116 ((Success != XGetWindowProperty (DISPLAY, pCD->client,
117 XA_WM_NORMAL_HINTS, 0L, (long)PROP_SIZE_HINTS_ELEMENTS,
118 False, XA_WM_SIZE_HINTS, &actualType, &actualFormat,
119 &nitems, &leftover, (unsigned char **)&property)) ||
120 (actualType != XA_WM_SIZE_HINTS) ||
121 (nitems < (PROP_SIZE_HINTS_ELEMENTS - 3)) ||
122 (actualFormat != 32)))
125 * Indicate no property values were retrieved:
128 sizeHints.icccVersion = ICCC_UNKNOWN;
134 * Parse the hint values out of the property data:
137 sizeHints.flags = property->flags;
138 sizeHints.x = property->x;
139 sizeHints.y = property->y;
140 sizeHints.width = property->width;
141 sizeHints.height = property->height;
142 sizeHints.min_width = property->minWidth;
143 sizeHints.min_height = property->minHeight;
144 sizeHints.max_width = property->maxWidth;
145 sizeHints.max_height = property->maxHeight;
146 sizeHints.width_inc = property->widthInc;
147 sizeHints.height_inc = property->heightInc;
148 sizeHints.min_aspect.x = (int)property->minAspectX;
149 sizeHints.min_aspect.y = (int)property->minAspectY;
150 sizeHints.max_aspect.x = (int)property->maxAspectX;
151 sizeHints.max_aspect.y = (int)property->maxAspectY;
154 if (nitems == (PROP_SIZE_HINTS_ELEMENTS - 3))
160 sizeHints.icccVersion = ICCC_R2;
165 * This is ICCC_CURRENT.
168 sizeHints.icccVersion = ICCC_CURRENT;
169 sizeHints.base_width = property->baseWidth;
170 sizeHints.base_height = property->baseHeight;
171 sizeHints.win_gravity = property->winGravity;
177 * Free the property data buffer:
182 XFree ((char *)property);
187 * Return the hints values:
193 } /* END OF FUNCTION GetNormalHints */
197 /*************************************<->*************************************
199 * ProcessWmProtocols (pCD)
204 * This function reads and processes the WM_PROTOCOLS property that is
205 * associated with a client window.
207 * ICCC_COMPLIANT check added to allow older clients to work, for now...
208 * eventually, this code should be removed.
212 * pCD = pointer to client data
217 * pCD = (clientProtocols, clientProtocolCount, protocolFlags)
219 *************************************<->***********************************/
221 void ProcessWmProtocols (ClientData *pCD)
224 Atom *property = NULL;
225 #ifndef ICCC_COMPLIANT
228 unsigned long leftover;
229 unsigned long nitems;
232 #endif /* ICCC_COMPLIANT */
236 if (pCD->clientProtocols)
238 XtFree ((char *)pCD->clientProtocols);
239 pCD->clientProtocols = NULL;
241 pCD->clientProtocolCount = 0;
242 pCD->protocolFlags = 0;
246 * Read the WM_PROTOCOLS property.
249 #ifndef ICCC_COMPLIANT
250 if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
253 rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_WM_PROTOCOLS, 0L,
254 (long)MAX_CLIENT_PROTOCOL_COUNT, False, AnyPropertyType,
255 &actualType, &actualFormat, &nitems, &leftover,
256 (unsigned char **)&property);
259 if ((rValue != Success) || (actualType == None) || (actualFormat != 32))
261 if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
264 rValue = XGetWMProtocols (DISPLAY, pCD->client,
265 (Atom **)&property, &nitems);
268 #endif /* ICCC_COMPLIANT */
271 * WM_PROTOCOLS does not exist or it is an invalid type or size.
274 pCD->clientProtocols = NULL;
278 if (!(pCD->clientProtocols = (Atom *)XtMalloc (nitems * sizeof (Atom))))
280 /* unable to allocate space */
281 Warning (((char *)GETMESSAGE(54, 1, "Insufficient memory for window management data")));
286 * Save the protocols in the client data and look for predefined
290 pCD->clientProtocolCount = nitems;
292 for (i = 0; i < nitems; i++)
294 pCD->clientProtocols[i] = property[i];
295 if (property[i] == wmGD.xa_WM_SAVE_YOURSELF)
297 pCD->protocolFlags |= PROTOCOL_WM_SAVE_YOURSELF;
299 else if (property[i] == wmGD.xa_WM_TAKE_FOCUS)
301 pCD->protocolFlags |= PROTOCOL_WM_TAKE_FOCUS;
303 else if (property[i] == wmGD.xa_WM_DELETE_WINDOW)
305 pCD->protocolFlags |= PROTOCOL_WM_DELETE_WINDOW;
307 else if (property[i] == wmGD.xa_MWM_MESSAGES)
309 pCD->protocolFlags |= PROTOCOL_MWM_MESSAGES;
318 XFree ((char *)property);
322 } /* END OF FUNCTION ProcessWmProtocols */
326 /*************************************<->*************************************
328 * ProcessMwmMessages (pCD)
333 * This function reads and processes the _MWM_MESSAGES property that is
334 * associated with a client window.
339 * pCD = pointer to client data
344 * pCD = (mwmMessagesCount, mwmMessages)
346 *************************************<->***********************************/
348 void ProcessMwmMessages (ClientData *pCD)
351 long *property = NULL;
354 unsigned long leftover;
355 unsigned long nitems;
359 if (pCD->mwmMessages)
361 XtFree ((char *)pCD->mwmMessages);
362 pCD->mwmMessages = NULL;
364 pCD->mwmMessagesCount = 0;
368 * Read the _MWM_MESSAGES property.
371 if (!HasProperty (pCD, wmGD.xa_MWM_MESSAGES))
374 rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_MESSAGES, 0L,
375 (long)MAX_MWM_MESSAGES_COUNT, False, AnyPropertyType,
376 &actualType, &actualFormat, &nitems, &leftover,
377 (unsigned char **)&property);
380 if ((rValue != Success) || (actualType == None) || (actualFormat != 32)
384 * _MWM_MESSAGES does not exist or it is an invalid type.
387 pCD->mwmMessages = NULL;
391 if (!(pCD->mwmMessages = (long *)XtMalloc (nitems * sizeof (long))))
393 /* unable to allocate space */
394 Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
399 * Save the protocols in the client data and look for predefined
403 pCD->mwmMessagesCount = nitems;
405 for (i = 0; i < nitems; i++)
407 if ((pCD->mwmMessages[i] = property[i]) == wmGD.xa_MWM_OFFSET)
409 pCD->protocolFlags |= PROTOCOL_MWM_OFFSET;
418 XFree ((char *)property);
422 } /* END OF FUNCTION ProcessMwmMessages */
426 /*************************************<->*************************************
428 * SetMwmInfo (propWindow, flags, wmWindow)
433 * This function sets up the _MOTIF_WM_INFO property on the specified (usually
439 * propWindow = window on which the _MOTIF_WM_INFO property is to be set
441 * flags = motifWmInfo.flags value
443 * wmWindow = motifWmInfo.wmWindow value
448 * _MWM_INFO = this property is set on the specified window
450 *************************************<->***********************************/
452 void SetMwmInfo (Window propWindow, long flags, Window wmWindow)
454 PropMwmInfo property;
457 property.flags = flags;
458 property.wmWindow = wmWindow;
460 XChangeProperty (DISPLAY, propWindow, wmGD.xa_MWM_INFO, wmGD.xa_MWM_INFO,
461 32, PropModeReplace, (unsigned char *)&property,
462 PROP_MWM_INFO_ELEMENTS);
464 } /* END OF FUNCTION SetMwmInfo */
467 /*************************************<->*************************************
469 * SetMwmSaveSessionInfo (wmWindow)
474 * This function sets up the WM_SAVE_YOURSELF property on the wm window
479 * wmWindow = motifWmInfo.wmWindow
484 * WM_SAVE_YOURSELF = this property is set on the wm window
486 *************************************<->***********************************/
488 void SetMwmSaveSessionInfo (Window wmWindow)
492 property = wmGD.xa_WM_SAVE_YOURSELF;
494 XChangeProperty (DISPLAY, wmWindow,
495 wmGD.xa_WM_PROTOCOLS, XA_ATOM,
497 (unsigned char *) &property, 1);
498 SetWMState(wmWindow, NORMAL_STATE, 0);
500 } /* END OF FUNCTION SetMwmSaveSessionInfo */
504 /*************************************<->*************************************
506 * GetWMState (window)
511 * This function gets the WM_STATE property on a client top-level
517 * window = client window from which the WM_STATE property is to be retrieved
522 * RETURN = a pointer to the WM_STATE property value (NULL if not defined)
527 * This function will eventually be superseded when WM_STATE support is
528 * added to the official X release.
530 *************************************<->***********************************/
537 PropWMState *property = NULL;
540 unsigned long nitems;
541 unsigned long leftover;
544 ret_val = XGetWindowProperty (DISPLAY, window, wmGD.xa_WM_STATE,
545 0L, PROP_WM_STATE_ELEMENTS,
546 False, wmGD.xa_WM_STATE,
547 &actual_type, &actual_format,
548 &nitems, &leftover, (unsigned char **)&property);
550 if (!((ret_val == Success) && (actual_type == wmGD.xa_WM_STATE) &&
551 (nitems == PROP_WM_STATE_ELEMENTS)))
554 * The property could not be retrieved or is not correctly set up.
559 XFree ((char *)property);
566 } /* END OF FUNCTION GetWMState */
570 /*************************************<->*************************************
572 * SetWMState (window, state, icon)
577 * This function sets up the WM_STATE property on a client top-level
583 * window = client window on which the WM_STATE property is to be set
585 * state = state of the client application
587 * icon = window manager's icon window
592 * WM_STATE = this property is set on the client window
597 * This function will eventually be superseded when WM_STATE support is
598 * added to the official X release.
600 *************************************<->***********************************/
602 void SetWMState (Window window, int state, Window icon)
604 PropWMState property;
607 property.state = state;
608 property.icon = icon;
610 XChangeProperty (DISPLAY, window, wmGD.xa_WM_STATE, wmGD.xa_WM_STATE, 32,
611 PropModeReplace, (unsigned char *)&property, PROP_WM_STATE_ELEMENTS);
613 } /* END OF FUNCTION SetWMState */
617 /*************************************<->*************************************
625 * This function reads any _MWM_HINTS property that is associated with a
630 * pCD = pointer to client data
634 * RETURN = ptr to mwm hints property, or NULL ptr if failure
636 *************************************<->***********************************/
644 PropMwmHints *property = NULL;
647 unsigned long nitems;
648 unsigned long leftover;
651 if (!HasProperty(pCD, wmGD.xa_MWM_HINTS))
654 ret_val = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_HINTS,
655 0L, PROP_MWM_HINTS_ELEMENTS,
656 False, wmGD.xa_MWM_HINTS,
657 &actual_type, &actual_format,
658 &nitems, &leftover, (unsigned char **)&property);
661 * Retrieve the property data.
663 * Motif 1.1.n clients: nitems = PROP_MWM_HINTS_ELEMENTS
664 * Motif 1.2 clients: nitems = PROP_MWM_HINTS_ELEMENTS + 2
666 * NOTES: We don't need to check (nitems == PROP_MWM_HINTS_ELEMENTS)
669 * If running Motif 1.1.n client with Mwm 1.2, then ignore extra elements
670 * since property.flags won't have extra elements set.
672 * If running Motif 1.2 client with Mwm 1.1.n, then ignore extra elements
673 * since Mwm 1.1.n won't try to access the extra elements.
676 if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_HINTS))
678 return (property); /* indicate success */
683 * The property could not be retrieved or is not correctly set up.
688 XFree ((char *)property);
691 return (NULL); /* indicate failure */
694 } /* END OF FUNCTION GetMwmHints */
698 /*************************************<->*************************************
701 * GetMwmInfo (rootWindowOfScreen)
706 * This function reads the _MOTIF_WM_INFO property from the root window if
711 * pSD = pointer to screen data
715 * RETURN = ptr to motif wm info property, or NULL ptr if no property
717 *************************************<->***********************************/
719 PropMwmInfo *GetMwmInfo (Window rootWindowOfScreen)
722 PropMwmInfo *property = NULL;
725 unsigned long nitems;
726 unsigned long leftover;
729 ret_val = XGetWindowProperty (DISPLAY, rootWindowOfScreen,
731 0L, PROP_MWM_INFO_ELEMENTS,
732 False, wmGD.xa_MWM_INFO,
733 &actual_type, &actual_format,
735 (unsigned char **)&property);
737 if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_INFO) &&
738 (nitems == PROP_MWM_INFO_ELEMENTS))
740 return (property); /* indicate success */
745 * The property could not be retrieved or is not correctly set up.
750 XFree ((char *)property);
753 return (NULL); /* indicate failure */
756 } /* END OF FUNCTION GetMwmInfo */
760 /*************************************<->*************************************
762 * ProcessWmColormapWindows (pCD)
767 * This function retrieves and processes the WM_COLORMAP_WINDOWS client
773 * pCD = pointer to client data
778 * pCD = (cmapWindows, clientCmapList, clientCmapCount, clientCmapIndex)
780 *************************************<->***********************************/
782 void ProcessWmColormapWindows (ClientData *pCD)
785 Window *property = NULL;
788 unsigned long leftover;
789 unsigned long nitems;
792 Colormap *pColormaps;
794 XWindowAttributes wAttributes;
796 XSetWindowAttributes sAttributes;
797 #ifndef OLD_COLORMAP /* colormaps */
803 * pCD->clientCmapCount and pCD->clientCmapIndex are initialized in
808 * Read the WM_COLORMAP_WINDOWS property.
811 rValue = XGetWindowProperty (DISPLAY, pCD->client,
812 wmGD.xa_WM_COLORMAP_WINDOWS, 0L,
813 (long)MAX_COLORMAP_WINDOWS_COUNT, False, AnyPropertyType,
814 &actualType, &actualFormat, &nitems, &leftover,
815 (unsigned char **)&property);
818 if ((rValue == Success) && (actualType != None) && (actualFormat == 32) &&
822 * WM_COLORMAP_WINDOWS exists and is a valid type.
825 if (!(pWindows = (Window *)XtMalloc ((nitems * sizeof (Window)) + 1)) ||
826 !(pColormaps = (Colormap *)XtMalloc ((nitems*sizeof(Colormap)) + 1)))
828 /* unable to allocate space */
829 Warning (((char *)GETMESSAGE(54, 3, "Insufficient memory for window management data")));
832 XtFree ((char *)pWindows);
835 #ifndef OLD_COLORMAP /* colormap */
836 /* Is the above OSF code a bug -- allocates one extra byte, rather */
837 /* than one extra element, for the top window if needed? */
838 else if ( ! (pCmapFlags = (int *)XtCalloc(nitems+1,sizeof(int)))) {
839 /* unable to allocate space */
840 Warning (((char *)GETMESSAGE(54, 4, "Insufficient memory for window manager flags")));
841 XtFree ((char *)pWindows); XtFree ((char *)pColormaps);
847 * Check to see if the top-level client window is in the list.
848 * If it is not then add it to the head of the list.
851 for (i = 0; i < nitems; i++)
853 if (property[i] == pCD->client)
862 /* add the client window to the colormap window list */
863 pWindows[0] = pCD->client;
864 pColormaps[0] = FindColormap (pCD, pCD->client);
868 sAttributes.event_mask = (ColormapChangeMask);
869 for (i = 0; i < nitems; i++)
871 if ((pColormaps[colormapCount] =
872 FindColormap (pCD, property[i])) != None)
874 pWindows[colormapCount] = property[i];
877 else if (XFindContext (DISPLAY, property[i],
878 wmGD.windowContextType, (caddr_t *)&pcd))
881 * The window is not a top level window or a window that
882 * is already being tracked for colormap changes.
883 * Track colormap attribute changes.
886 XChangeWindowAttributes (DISPLAY, property[i], CWEventMask,
890 if (XGetWindowAttributes (DISPLAY, property[i],
893 pWindows[colormapCount] = property[i];
894 pColormaps[colormapCount] = wAttributes.colormap;
901 * Free up the old colormap window data if it has been set. Set
902 * new window contexts.
905 ResetColormapData (pCD, pWindows, colormapCount);
909 * Set the colormap window data.
912 pCD->clientColormap = pColormaps[0];
913 if (colormapCount > 1)
916 * The top level window and at least one other window is in
917 * the colormap windows list.
920 pCD->clientCmapCount = colormapCount;
921 pCD->cmapWindows = pWindows;
922 pCD->clientCmapList = pColormaps;
923 pCD->clientCmapIndex = 0;
924 #ifndef OLD_COLORMAP /* colormap */
925 pCD->clientCmapFlags = pCmapFlags;
931 * Only the top level window is being tracked for colormap
935 pCD->clientCmapCount = 0;
936 XtFree ((char *)pWindows);
937 XtFree ((char *)pColormaps);
938 #ifndef OLD_COLORMAP /* colormap */
939 XtFree((char *)pCmapFlags);
948 XFree ((char *)property);
952 } /* END OF FUNCTION ProcessWmColormapWindows */
956 /*************************************<->*************************************
958 * FindColormap (pCD, window)
963 * This function checks colormap information that is currently saved in
964 * the client data for the colormap of the specified window.
969 * pCD = pointer to client data
971 * window = get the colormap id for this window
976 * RETURN = colormap id for window (NULL if no colormap information)
978 *************************************<->***********************************/
980 Colormap FindColormap (ClientData *pCD, Window window)
982 Colormap colormap = (Colormap)0;
986 if (pCD->clientCmapCount == 0)
989 * If the colormap count is 0 there is no list of colormaps and
990 * clientColormap is the colormap of the top-level window.
993 if (window == pCD->client)
995 colormap = pCD->clientColormap;
1000 for (i = 0; i < pCD->clientCmapCount; i++)
1002 if (pCD->cmapWindows[i] == window)
1004 colormap = pCD->clientCmapList[i];
1012 } /* END OF FUNCTION FindColormap */
1016 /*************************************<->*************************************
1018 * GetMwmMenuItems (pCD)
1023 * This function reads and processes any _MWM_MENU property that is
1024 * associated with a client window and returns a list of MenuItem structures
1025 * specified by the property, or NULL.
1030 * pCD = pointer to client data
1035 * Return = MenuItem list or NULL.
1037 *************************************<->***********************************/
1044 XTextProperty textProperty;
1045 MenuItem *menuItems;
1048 * Read the _MWM_MENU property.
1051 textProperty.value = (unsigned char *)NULL;
1052 rValue = XGetTextProperty(DISPLAY, pCD->client, &textProperty,
1054 if ((rValue == 0) || (textProperty.value == (unsigned char *)NULL))
1055 /* _MWM_MENU does not exist or it is an invalid type. */
1061 /* parse the property string */
1066 if (XmbTextPropertyToTextList(DISPLAY, &textProperty,
1067 &textList, &nItems) != Success)
1073 menuItems = ParseMwmMenuStr (PSD_FOR_CLIENT(pCD),
1074 (unsigned char *)textList[0]);
1075 XFreeStringList(textList);
1078 XFree((void *)textProperty.value);
1083 } /* END OF FUNCTION GetMwmMenuItems */
1087 /*************************************<->*************************************
1089 * GetWorkspaceHints (display, window, ppWsAtoms, pCount, pbAll)
1094 * Get the contents of the WM_COMMAND property on a window
1099 * display - X display
1100 * window - window to get hints from
1101 * ppWsAtoms - pointer to a list of workspace atoms (to be returned)
1102 * pCount - ptr to a number of atoms (to be returned)
1103 * pbAll - ptr to a boolean (to be returned)
1108 * Success if suceeded, otherwise failure code.
1113 * *ppWsAtoms - list of workspace atoms
1114 * *pCount - number of atoms in *ppWsAtoms
1115 * *pbAll - True if should put in all workspaces
1120 * The caller must XtFree *ppWsAtoms when done!!!
1122 *************************************<->***********************************/
1124 Status GetWorkspaceHints (Display *display, Window window,
1125 Atom **ppWsAtoms, unsigned int *pCount,
1129 DtWorkspaceHints *pWsHints;
1132 rcode = _DtWsmGetWorkspaceHints(display, window, &pWsHints);
1133 if (rcode == Success)
1135 if (pWsHints->flags & DT_WORKSPACE_HINTS_WORKSPACES)
1138 XtMalloc (pWsHints->numWorkspaces * sizeof(Atom));
1140 pWsHints->pWorkspaces,
1141 (pWsHints->numWorkspaces * sizeof(Atom)));
1143 *pCount = pWsHints->numWorkspaces;
1152 if ((pWsHints->flags & DT_WORKSPACE_HINTS_WSFLAGS) &&
1153 (pWsHints->wsflags & DT_WORKSPACE_FLAGS_OCCUPY_ALL))
1163 _DtWsmFreeWorkspaceHints (pWsHints);
1168 } /* END OF FUNCTION GetWorkspaceHints */
1171 /*************************************<->*************************************
1173 * SetEmbeddedClientsProperty (propWindow, pEmbeddedClients,
1179 * This function writes the _DT_WORKSPACE_EMBEDDED_CLIENTS property
1184 * propWindow = window on which the property is to be written
1185 * pEmbeddedClients = pointer to data (array of window IDs)
1186 * cEmbeddedClients = number of window IDs in the array
1188 *************************************<->***********************************/
1190 void SetEmbeddedClientsProperty (Window propWindow,
1191 Window *pEmbeddedClients, unsigned long cEmbeddedClients)
1193 XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_EMBEDDED_CLIENTS,
1194 wmGD.xa_DT_EMBEDDED_CLIENTS,
1195 32, PropModeReplace, (unsigned char *)pEmbeddedClients,
1198 } /* END OF FUNCTION SetEmbeddedClientsProperty */
1202 /*************************************<->*************************************
1204 * SetWorkspaceInfo (propWindow, pWsInfo, cInfo)
1209 * This function sets up the _DT_WORKSPACE_INFO property
1214 * propWindow = window on which the _DT_WORKSPACE_INFO property is to be set
1215 * pWsInfo = pointer to workspace info data
1216 * cInfo = size of workspace info data
1219 *************************************<->***********************************/
1221 void SetWorkspaceInfo (Window propWindow, WorkspaceInfo *pWsInfo, unsigned long cInfo)
1223 XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_WORKSPACE_INFO,
1224 wmGD.xa_DT_WORKSPACE_INFO,
1225 32, PropModeReplace, (unsigned char *)pWsInfo,
1226 (cInfo * sizeof(WorkspaceInfo))/sizeof(long));
1228 } /* END OF FUNCTION SetWorkspaceInfo */
1232 /*************************************<->*************************************
1234 * SetWorkspaceListProperty (pSD)
1239 * This function sets up the _DT_WORKSPACE_LIST property
1244 * pSD = ptr to screen data
1247 *************************************<->***********************************/
1250 SetWorkspaceListProperty (WmScreenData *pSD)
1252 WmWorkspaceData *pws;
1257 XtMalloc (pSD->numWorkspaces * sizeof(Atom));
1260 for (count = 0; count < pSD->numWorkspaces; count++)
1262 pWsList[count] = pws->id;
1266 XChangeProperty (DISPLAY, pSD->wmWorkspaceWin,
1267 wmGD.xa_DT_WORKSPACE_LIST,
1269 32, PropModeReplace, (unsigned char *)pWsList,
1270 (pSD->numWorkspaces * sizeof(Atom))/sizeof(long));
1272 XtFree ((char *) pWsList);
1274 } /* END OF FUNCTION SetWorkspaceListProperty */
1277 /*************************************<->*************************************
1279 * SetCurrentWorkspaceProperty (pSD)
1284 * This function sets up the _DT_WORKSPACE_CURRENT property
1289 * pSD = ptr to screen data
1292 *************************************<->***********************************/
1295 SetCurrentWorkspaceProperty (WmScreenData *pSD)
1299 aCurrent = pSD->pActiveWS->id;
1301 XChangeProperty (DISPLAY, pSD->wmWorkspaceWin,
1302 wmGD.xa_DT_WORKSPACE_CURRENT,
1304 32, PropModeReplace, (unsigned char *)&aCurrent,
1305 (sizeof(Atom))/sizeof(long));
1307 XSync (DISPLAY, False); /* XFlush didn't work here, why? */
1309 } /* END OF FUNCTION SetCurrentWorkspaceProperty */
1312 /*************************************<->*************************************
1314 * SetWorkspaceInfoProperty (pWS)
1319 * This function sets up the _DT_WORKSPACE_INFO_<name> property
1320 * for a particular workspace
1325 * pWS = ptr to workspace data
1328 *************************************<->***********************************/
1331 SetWorkspaceInfoProperty (WmWorkspaceData *pWS)
1342 #define WIP_NUMBER_SIZE 16
1345 * Construct our property name
1347 pch = WorkspacePropertyName (pWS);
1349 aProperty = XmInternAtom (DISPLAY, pch, FALSE);
1351 XtFree ((char *) pch);
1354 * Determine the number of strings in our vector. One for each of
1358 * backdrop background
1359 * backdrop foreground
1361 * number of backdrop windows
1362 * list of backdrop windows
1364 iNumStrings = 6; /* number of fields minus backdrop window(s) */
1365 count = 1; /* number of backdrop windows */
1366 iNumStrings += count;
1368 /* allocate string vector */
1369 ppchList = (char **) XtMalloc (iNumStrings * sizeof (char *));
1370 pch = (char *) XtMalloc (iNumStrings * WIP_NUMBER_SIZE * sizeof(char));
1374 /* Convert workspace title to ascii */
1375 sTitle = (String) WmXmStringToString (pWS->title);
1376 ppchList[i++] = (char *) sTitle;
1379 ix = (i * WIP_NUMBER_SIZE);
1380 sprintf (&pch[ix], "%d", pWS->backdrop.colorSet);
1381 ppchList[i++] = &pch[ix];
1383 /* backdrop background */
1384 ix = (i * WIP_NUMBER_SIZE);
1385 sprintf (&pch[ix], "0x%lx", pWS->backdrop.background);
1386 ppchList[i++] = &pch[ix];
1388 /* backdrop foreground */
1389 ix = (i * WIP_NUMBER_SIZE);
1390 sprintf (&pch[ix], "0x%lx", pWS->backdrop.foreground);
1391 ppchList[i++] = &pch[ix];
1394 ix = (i * WIP_NUMBER_SIZE);
1395 sprintf (&pch[ix], "0x%lx", pWS->backdrop.nameAtom);
1396 ppchList[i++] = &pch[ix];
1398 /* number of backdrop windows */
1399 ix = (i * WIP_NUMBER_SIZE);
1400 if (pWS->backdrop.window == None)
1402 strcpy (&pch[ix], "0");
1406 sprintf (&pch[ix], "%d", count);
1408 ppchList[i++] = &pch[ix];
1410 /* backdrop windows */
1412 * One or zero backdrop windows
1413 * (NULL written if zero)
1415 ix = (i * WIP_NUMBER_SIZE);
1416 sprintf (&pch[ix], "0x%lx", pWS->backdrop.window);
1417 ppchList[i++] = &pch[ix];
1420 * Write out the property
1422 status = XmbTextListToTextProperty (DISPLAY, ppchList, iNumStrings,
1423 XStdICCTextStyle, &tp);
1424 if ((status == Success) || (status > 0))
1427 * Complete or partial conversion
1429 XSetTextProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, &tp, aProperty);
1433 XtFree ((char *) ppchList);
1435 if (sTitle) XtFree ((char *)sTitle);
1437 } /* END OF FUNCTION SetWorkspaceInfoProperty */
1440 /*************************************<->*************************************
1442 * DeleteWorkspaceInfoProperty (pWS)
1447 * This function deletes a _DT_WORKSPACE_INFO_<name> property
1448 * for a particular workspace
1453 * pWS = ptr to workspace data
1456 *************************************<->***********************************/
1459 DeleteWorkspaceInfoProperty (WmWorkspaceData *pWS)
1465 * Get the atom for the workspace property.
1467 pch = WorkspacePropertyName (pWS);
1469 aProperty = XmInternAtom (DISPLAY, pch, FALSE);
1471 XtFree ((char *) pch);
1474 * Do the property deletion
1476 XDeleteProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, aProperty);
1480 } /* END OF FUNCTION DeleteWorkspaceInfoProperty */
1483 /*************************************<->*************************************
1485 * WorkspacePropertyName (pWS)
1490 * This function returns a string containing the property name for a
1496 * pWS = ptr to workspace data
1500 * string containing the workspace property name (Free with XtFree)
1503 *************************************<->***********************************/
1506 WorkspacePropertyName (WmWorkspaceData *pWS)
1513 * Construct our property name
1515 pchName = pWS->name;
1516 len = strlen(pchName) + strlen (_XA_DT_WORKSPACE_INFO) + 4;
1518 pch = (char *) XtMalloc (len);
1519 strcpy (pch, _XA_DT_WORKSPACE_INFO);
1521 strcat (pch, pchName);
1525 } /* END OF FUNCTION WorkspacePropertyName */
1528 /*************************************<->*************************************
1530 * SetWorkspacePresence (propWindow, pWsPresence, cPresence)
1535 * This function sets up the _DT_WORKSPACE_PRESENCE property
1540 * propWindow = window on which the _DT_WORKSPACE_PRESENCE property
1542 * pWsPresence = pointer to workspace presence data
1543 * cPresence = size of workspace presence data
1546 *************************************<->***********************************/
1548 void SetWorkspacePresence (Window propWindow, Atom *pWsPresence, unsigned long cPresence)
1550 XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_WORKSPACE_PRESENCE,
1551 wmGD.xa_DT_WORKSPACE_PRESENCE, 32, PropModeReplace,
1552 (unsigned char *)pWsPresence, cPresence);
1555 } /* END OF FUNCTION SetWorkspacePresence */
1560 /*************************************<->*************************************
1562 * GetDtSessionHints (pSD, sNum)
1567 * This function reads and processes _DT_SESSION_HINTS property that is
1568 * associated with the root window of each screen managed by dtwm
1578 *************************************<->***********************************/
1580 void GetDtSessionHints (WmScreenData *pSD, int sNum)
1585 char *property = NULL;
1588 unsigned long leftover;
1589 unsigned long nitems;
1594 * Read the property.
1597 rValue = XGetWindowProperty (DISPLAY, pSD->rootWindow,
1598 wmGD.xa_DT_SESSION_HINTS, 0L,
1599 (long)1000000, False, AnyPropertyType,
1600 &actualType, &actualFormat, &nitems,
1601 &leftover, (unsigned char **)&property);
1604 if ((rValue != Success) || (actualType == None) || (actualFormat != 8))
1605 /* _DT_SESSION_HINTS does not exist or it is an invalid type. */
1607 pSD->pDtSessionItems = NULL;
1612 /* parse the property string */
1614 ParseDtSessionHints (pSD, (unsigned char *)property);
1620 XFree ((char *)property);
1624 * Delete the property so we don't see it if the user
1627 #ifndef DEBUG_SESSION_HINTS
1628 XDeleteProperty (DISPLAY, pSD->rootWindow, wmGD.xa_DT_SESSION_HINTS);
1629 #endif /* DEBUG_SESSION_HINTS */
1630 } /* END OF FUNCTION GetDtSessionHints */
1635 /*************************************<->*************************************
1637 * GetDtWmRequest (pSD, pszReq, pmore)
1642 * This function returns the next request
1647 * pSD - pointer to screen data
1648 * psdReq - pointer to a char pointer
1653 * *pszReq - pointer to null terminated string containing next
1655 * *pmore - set to true if more data is left in the property
1659 * The data for pszReq is allocated in here. The caller must free up
1660 * this space using XtFree.
1663 *************************************<->***********************************/
1674 char *chRequest = NULL;
1675 static char *property = NULL;
1676 static int iNext = -1;
1680 unsigned long leftover;
1681 static unsigned long nitems = 0;
1685 * We need to read the property again if we have no data left
1686 * over from last time;
1688 if (property == NULL)
1692 * Lock down the server to prevent changes to this
1693 * property while we "edit" it.
1695 XGrabServer(DISPLAY);
1696 #endif /* PARANOID */
1699 * Read the property and delete it.
1701 rValue = XGetWindowProperty (DISPLAY, pSD->wmWorkspaceWin,
1702 wmGD.xa_DT_WM_REQUEST, 0L,
1703 (long)1000000, True, AnyPropertyType,
1704 &actualType, &actualFormat, &nitems,
1705 &leftover, (unsigned char **)&property);
1708 /* Give the server back */
1709 XUngrabServer(DISPLAY);
1710 #endif /* PARANOID */
1713 * Validate the property that we've read
1715 if ((rValue != Success) ||
1716 (actualType == None) ||
1717 (actualFormat != 8))
1719 /* The property does not exist or it is an invalid type. */
1726 /* the property is fine, set the index of the next char. */
1733 * If we've got something, then extract and return the next
1736 if (property && iNext >= 0)
1740 for (i=iNext; i<nitems; i++)
1742 if (property [i] == '\0')
1747 if (i>=nitems) i=nitems;
1749 len = i - iNext + 1 + ((property[i] == '\0') ? 0 : 1);
1751 chRequest = (char *) XtMalloc (len);
1752 if (chRequest == NULL)
1754 Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
1758 /* dequeue the request */
1759 strncpy (chRequest, &property[iNext], len);
1760 if (property[i] != '\0')
1762 chRequest[len-1]='\0';
1767 if (iNext >= nitems)
1770 * Extracted the last request, free up the storage
1771 * and reset for next time.
1773 XFree ((char *)property);
1779 *pmore = (property != NULL);
1780 *pszReq = chRequest;
1782 } /* END OF FUNCTION GetDtWmRequest */
1785 /*************************************<->*************************************
1787 * GetIntialPropertyList (ClientData *)
1792 * Get the list of initial properties on the window
1797 * pCD - pointer to client data
1802 * pCD - paInitialProperties member is updated
1807 * The caller must XFree the paIntialialProperties member!
1809 *************************************<->***********************************/
1812 GetInitialPropertyList (ClientData *pCD)
1817 paList = XListProperties (DISPLAY, pCD->client, &iProps);
1821 pCD->paInitialProperties = paList;
1822 pCD->numInitialProperties = iProps;
1826 pCD->paInitialProperties = NULL;
1827 pCD->numInitialProperties = 0;
1830 } /* END OF FUNCTION GetInitialPropertyList */
1833 /*************************************<->*************************************
1835 * DiscardIntialPropertyList (ClientData *)
1840 * Tosses out the intial property list for a client, frees data
1845 * pCD - pointer to client data
1850 * pCD - paInitialProperties member is updated
1857 *************************************<->***********************************/
1860 DiscardInitialPropertyList (ClientData *pCD)
1862 if (pCD->paInitialProperties)
1865 * Free the initial property list.
1866 * (see HasProperty() function)
1868 XFree ((char *) pCD->paInitialProperties);
1869 pCD->paInitialProperties = NULL;
1870 pCD->numInitialProperties = 0;
1872 } /* END OF FUNCTION DiscardInitialPropertyList */
1875 /*************************************<->*************************************
1877 * HasProperty (pCD, aProperty)
1882 * Returns True if this client had this property when it was mapped
1887 * pCD - pointer to client data
1888 * aProperty - atom of property to test for
1893 * Return - True if this property was on the initial list for this
1894 * client; False otherwise.
1900 *************************************<->***********************************/
1907 Boolean bFound = False;
1911 paList = pCD->paInitialProperties;
1915 count = pCD->numInitialProperties;
1916 while ((!bFound) && (count > 0))
1918 bFound = (*paList == aProperty);
1926 * The property list doesn't exist. Return
1927 * True to force a read of this property. The most likely
1928 * case is that this property was updated after the
1929 * window was managed and needs to be read.
1935 } /* END OF FUNCTION HasProperty */